9

使用Thread类和Runnable接口实现多线程的区别 - 知识焦虑症患者

 2 years ago
source link: https://www.cnblogs.com/xiaobaiLX/p/16452529.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用Thread类和Runnable接口实现多线程的区别

先看两种实现方式的步骤:

public class ThreadDemo{
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            //创建并启动由继承Thread类创建的线程
            new Thread(new MyThread(),"Thread"+i).start();
             //创建并启动由实现Runnable接口创建的线程
            new Thread(new Runner(),"Thread"+i).start();
        }
    }
}

//继承Thread类
class MyThread extends Thread{
    //重写run方法
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"由继承Thread创建");
    }
}

//实现Runnable接口
class Runner implements Runnable{
    //实现run方法
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"有实现Runnable接口创建");
    }
}

从上面代码可以看出,当使用Runnable接口创建多线程时,需要将实现类作为参数出入到Thread实例对象中,通过调用Thread对象的start方法进行启动。我们来看一下Thread的源码

//Thread类继承了Runnable类
public class Thread implements Runnable {}

//Thread的构造函数调用了init方法
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
}

//init调用了静态方法init
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
}

//再看静态方法init
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
        ...
        //私有Runnable实例
        this.target = target;
        ...
}

//再看一下Runnable方法
@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

从以上追踪源码过程可以看出,Thread类实现了 Runnable 接口,而继承Thread类重写 run 方法本质就是实现Runnable接口的 run 方法。

通过以上分析,总结使用 Thread 类和 Runnable 接口的区别:

  1. 使用继承 Thread 类实现多线程相比于 Runnable 更加简单,使用 Runnable 接口需要使用 Thread进行再次封装。
  2. 由于 Java 中不支持多继承,一个类继承了 Thread 类后无法再继承其他类,因此使用 Runnable 接口实现多线程有更好的灵活性。

除了以上两种多线程实现方式,还可以使用 Callable 接口实现,我写了一篇关于 Callable 和 Runnable 接口实现多线程对比的总结:

使用Runnable和Callable接口实现多线程的区别


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK