• Java中Thread与Runnable二三事


    首先提出两个问题,带着这两个问题往下看:

    1.真正实现多线程,因为我自己刚开始学java的多线程时只知道,多线程是执行线程类的run方法,所以就在代码中手动调用了run方法,但实际上这么做是无效的。所以这里也简单写一下,算是给同样是初学者们的小提醒。

    2.实现线程间的资源共享

    java中实现多线程有两种方法:
    1.继承Thread类
    2.实现Runnable接口

    对于第一种方法、继承Thread类:

    首先我们知道,多线程就是执行线程类的run()方法,所以这里我们复写了线程类的run()方法,然后调用之。

    class MyThread extends Thread{
        int t = 10;
        String name = "";
        MyThread(String name){
            super(name);
            this.name = name;
        }
        public void run(){
            while(t > 0){
                System.out.println(name + ":" + t--);
            }
        }
    }
    
    class s1{
        public static void main(String args[]){
            MyThread m1 = new MyThread("m1");
            MyThread m2 = new MyThread("m2");
    
            m1.run();
            m2.run();
        }
    }

     输出结果:

    m1:10
    m1:9
    m1:8
    m1:7
    m1:6
    m1:5
    m1:4
    m1:3
    m1:2
     m1:1
     m2:10
     m2:9
     m2:8
     m2:7
     m2:6
     m2:5
     m2:4
     m2:3
     m2:2
     m2:1

    运行结果不难可以看出,这些输出都是有规律可循的,并没有像想象中那样实现多线程。

    这是因为:我们知道,一个线程实际运行的就是run方法里的代码。所以我们就直接调用了run方法,可是还有一点我们没有注意的,就是多线程需要有操作系统的支持。
    Thread类中定义的start方法中,调用了一个private native void start0()方法,这里的native表明,这个方法是本地方法,可以与底层操作系统交互,来开启操作系统的多线程支持。这就是JNI(Java Native Interface)java本地接口。所以单纯的调用run方法是不行的,要调用start方法才能真正的开启多线程

    上面的代码修22、23行改为:

    m1.start();
    m2.start();

    到这里我们的第1个问题也得到了解答。

    至于第二种方法,实现runnable接口的类声明与之前大同小异,只是在主函数中有所不同
    不同在于,一个实现runnable接口的类没有start方法,这就无法开启线程,不过别急,看看Thread类,他有一个构造方法public Thread(Runnable targer)。所以可以再代码中这样写:

    //这里假设 MyThread 类是一个实现了runnable接口的类
    MyThread my = new MyThread();
    new Thread(my).start;

    这样就可以通过一个Thread实例来间接开启一个线程。

    好了 现在我们来看看第二个问题,资源共享。最经典的就是买票问题:

    class MyThread implements Runnable{
        private static int ticket=10;
        public void run(){
            while(ticket>0){
                System.out.println(Thread.currentThread().getName()+':'+ticket--);
            }
        }
    }
    
     public class TestThread{
         public static void main(String[] args){
             MyThread mt=new MyThread();
             new Thread(mt).start();
             new Thread(mt).start();
             new Thread(mt).start();
             new Thread(mt).start();
         }
     }

    这样执行出来的就是三个线程同时操作一个数据,就像三个窗口在同时卖一趟火车票,一共有10张。

  • 相关阅读:
    CF1290E Cartesian Tree
    【LeetCode】11. 盛最多水的容器
    【LeetCode】10. 正则表达式匹配
    【LeetCode】9. 回文数
    【LeetCode】8. 字符串转换整数 (atoi)
    【LeetCode】7. 整数反转
    【LeetCode】6. Z 字形变换
    【LeetCode】5. 最长回文子串
    【LeetCode】4. 寻找两个正序数组的中位数[待补充]
    【LeetCode】3. 无重复字符的最长子串
  • 原文地址:https://www.cnblogs.com/lipijin/p/3081080.html
Copyright © 2020-2023  润新知