使用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 介面實現多執行緒對比的總結: