使用Thread類和Runnable介面實現多執行緒的區別

知識焦慮症患者發表於2022-07-06

使用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介面實現多執行緒的區別

相關文章