使用Thread類和Runnable介面實現多執行緒的區別
使用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 介面的區別:
- 使用繼承 Thread 類實現多執行緒相比於 Runnable 更加簡單,使用 Runnable 介面需要使用 Thread進行再次封裝。
- 由於 Java 中不支援多繼承,一個類繼承了 Thread 類後無法再繼承其他類,因此使用 Runnable 介面實現多執行緒有更好的靈活性。
除了以上兩種多執行緒實現方式,還可以使用 Callable 介面實現,我寫了一篇關於 Callable 和 Runnable 介面實現多執行緒對比的總結:
使用Runnable和Callable介面實現多執行緒的區別