Java——多线程实现的两种方式

创建新执行线程有两种方法。

一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。

例如,计算大于某一规定值的质数的线程可以写成:

class PrimeThread extends Thread {
         long minPrime;
         PrimeThread(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

然后,下列代码会创建并启动一个线程:

     PrimeThread p = new PrimeThread(143);
     p.start();
1,继承Thread
定义类继承Thread
重写run方法
把新线程要做的事写到run方法中
创建线程对象
开启新线程,内部会自动执行run方法

具体的多线程实现代码如下:

package com.yy.thread;

public class Demo2_Thread {
/**
 * 创建新执行线程有两种方法。
 * 一种方法是
 * ①将类声明为 Thread 的子类。
 * ②该子类应重写 Thread 类的 run 方法。
 * ③接下来可以分配并启动该子类的实例。
 * */
    public static void main(String[] args) {
        //开启一条线程
        Mythread mt = new Mythread();           //4,创建线程(Thread类)的子类对象
        mt.start();                             //5,开启线程,需要一定的时间,所以说,JVM会先执行for循环语句,也就是,会先输出bb,之后再输出aaaaaaa;然后再相互交替输出
        //public void start() : 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
//      mt.run();                               //如果这样调用,只是调用了run方法,执行run方法里面的for循环,线程还是主线程这一个线程,不会出现交替的多线程形式


        //主线程
        for (int i = 0; i < 100; i++) {         //为了便于观察多线程的执行,在主方法里面进行for循环
            System.out.println("bb");           //这个for循环就是主线程的,两条线程开启多线程便于观察
        }

        //两条线程相互交替进行,即多线程实现
    }

}
class Mythread extends Thread{                  //1,继承Thread
    public void run(){                          //2,重写run方法
        for (int i = 0; i < 100; i++) {         //3,将要执行的代码写到run方法中
            System.out.println("aaaaaaa");  
        }
    }
}

创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。

然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

采用这种风格的同一个例子如下所示:

     class PrimeRun implements Runnable {
         long minPrime;
         PrimeRun(long minPrime) {
             this.minPrime = minPrime;
         }

         public void run() {
             // compute primes larger than minPrime
              . . .
         }
     }

然后,下列代码会创建并启动一个线程:
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

     PrimeRun p = new PrimeRun(143);
     new Thread(p).start();
2,实现Runnable
定义类实现Runnable接口
实现run方法
把新线程要做的事先到run方法中
创建自定义的Runnable子类对象
创建Tread对象,传入Runnable
调用start()开启新线程,内部会自动调用Runnable的run()方法

具体的多线程实现代码如下:

package com.yy.thread;

public class Demo3_Thread {
/**
 * 创建线程的另一种方法是
 * ①声明实现 Runnable 接口的类。
 * ②该类然后实现 run 方法。
 * ③然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。
 * 
 * Runnable里面只有一个run()方法,实现Runnable只需要重写run()方法即可
 * 
 * 
 * 实现Runnable的原理
 * 查看源码:
 *      1,看Thread类的构造函数,传递了Runnable接口的引用
 *      2,通过init()方法找到传递的target给成员变量的target赋值
 *      3,查看run方法,发现run方法中有判断,如果target不为null就会调用Runnable接口子类对象的run方法
 * */
    public static void main(String[] args) {
        MyRunnable wsq = new MyRunnable();                  //4,创建Runnable的子类对象
//      Runnable target = wsq;                              //父类引用指向子类对象,new MyRunnable()这个是子类对象也就是wsq  

        Thread yy = new Thread(wsq);                        //5,将其当作参数传递给Thread的构造函数; wsq代表Runnable的子类对象
        yy.start();                                         //6,开启线程; Thread里面才有start()方法

//      new Thread(wsq).start();                            //这种方法与上面的两行代码实现的做用一样



        for (int i = 0; i < 100; i++) {
            System.out.println("你,陪我步入蝉夏,越过城市喧嚣,歌声还在游走,你榴花般的笑容");
        }

    }
}
class MyRunnable implements Runnable {                      //1,定义一个类,实现Runnable方法

    @Override   
    public void run() {                                     //2,重写run方法
        for (int i = 0; i < 100; i++) {                     //3,将要执行的代码写到run方法中
            System.out.println("我真的好想你,在每一个雨季。");           
        }
    }   
}

两种方法的区别:

  • a.继承Thread : 由于子类重写了Thread类的run(),当调用start()时,直接找子类的run()方法
  • b.实现Runnable : 构造函数中传入了Runnable的引用,成员变量记住了它,start()调用run()方法时内部判断成员变量Runnable的引用是否为空,不为空,编译时看的是Runnable的run(),运行时执行的时子类的run()方法

继承Thread(开发中优先考虑)

  • 好处:可以直接使用Thread类中的方法,代码简单

  • 弊端:如果已经有了父类,就不能有这个方法,因为java是单继承的

实现Runnable接口(实际上是对继承Thread的补充)

  • 好处:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口,接口是可以多实现的,拓展性强

  • 弊端:不能直接使用Thread中的方法,需要先获取到线程对象后,才能得到Thread的方法,代码复杂

猜你喜欢

转载自blog.csdn.net/qq_41264055/article/details/81238746