一、實現多線程的方法到底有幾種?
Oracle的官方文檔中,實現多線程的方法有兩種:
- 實現Runnable接口
- 繼承Thread類
官方文檔地址: https://docs.oracle.com/javase/8/docs/api/
二、簡單使用兩種方法實現多線程
1.實現Runnable接口
/**
* 實現多線程的方式1:實現Runnable接口
*/
public class RunnableTest implements Runnable{
public static void main(String[] args) {
Thread thread = new Thread(new RunnableTest());
thread.start();
}
// 實現Runnable接口的run()方法
@Override
public void run() {
System.out.println("Runnable實現多線程");
}
}
2.繼承Thread
/**
* 實現多線程的方式2:繼承Thread
*/
public class ThreadTest extends Thread{
public static void main(String[] args) {
new ThreadTest().start();
}
// 重寫Thread類的run()方法
@Override
public void run() {
System.out.println("Thread實現多線程");
}
}
三、兩種方法的對比
(1)通過實現Runnable接口來實現多線程這種方法更好
- 具體的線程任務內容應該與Thread解耦
- 使用繼承Thread來實現多線程,當需要創建其他線程任務時,就需要創建一個新的Thread,這種損耗是比較大的。使用Runnable可以使用線程池來節約資源。
- java單繼承的特性使得繼承了Thread的類無法繼承其他的類,限制了可拓展性。
(2)兩種方法的本質對比
- 方法1: new Thread(runnable)是傳入Runnable,調用了runnable.run()方法
- 方法2: Thread類的run()方法被重寫,直接調用了子類的run方法
其中target就是new Thread()時傳入的Runnable對象。
四、同時使用兩種方法
創建Thread對象時傳入Runnable,並且重寫Thread的run()方法
/**
* 同時使用兩種方法
*/
public class BothTest {
public static void main(String[] args) {
new Thread(new BothRunnable()){
@Override
public void run() {
System.out.println("我是Thread");
}
}.start();
}
}
class BothRunnable implements Runnable{
@Override
public void run() {
System.out.println("我是Runnable");
}
}
雖然在創建Thread對象時傳入了Runnable,也就是Thread源碼中的target存在,但是因爲重寫了Thread類的run()方法,原來的target.run()語句沒有了,所以並不會執行傳入runnable的run()方法。
五、實現多線程的方法最準確的描述
- 實現多線程的方法有兩類
- 準確的講,創建線程只有一種方式,就是構造Thread類,而實現線程執行單元有兩種方式:一是實現Runnable接口的run方法,並把Runnable實例傳給Thread;二是重寫Thread類的run方法。
六、其他的不準確的說法
線程池、定時器等也能創建線程,但是他們的底層都是基於 實現Runnable接口 或繼承Thread類 來實現的。