[英]What are the differences between these two ways of starting threads?
如果我有一個實現Runnable接口的類,那么main方法中這些語句之間的區別是什么?
MyThread t1 = new MyThread();
t1.start();
和
MyThread t2 = new MyThread();
new Thread(t2).start();
由於您做了t1.start()
,因此我假設MyThread擴展了Thread。 在這種情況下,第一個是正確的。
第二個創建新線程,然后在另一個線程中啟動任務。 浪費了一個線程。
要在Java中實現線程,您基本上有兩個選擇。 一:擴展Thread類並實現方法運行。 您的示例似乎就是這種情況。 在這種情況下,您應該調用Thread.class的start()方法。 那是您提供的兩個變量之一。
第二種變體是如果您實現Runnable-interface。 在這種情況下,您還實現了方法run,但是您的類沒有開始,因此您將Runnable作為參數創建了一個新的Thread-class(就像您在第二個示例中所做的那樣)。 但這沒有意義,如果您已經擴展了Thread。
我個人更喜歡實現Runnable,因為我不更改Thread(將對其進行擴展)的行為,而僅使用Thread-functionity。
假如說
class MyThread extends Thread
第一次調用將在新線程中啟動代碼。
通話
new Thread(new MyThread()).start();
也會在MyThread中運行您的代碼,因為Thread構造函數僅需要一個實現Runnable接口和run()方法的對象。 您的MyThread類已經具有此方法,因此它將由簡單的包裝線程執行。 還要注意,新的MyThread基本上仍然是未啟動的線程。
您可以嘗試以下小程序:
public class MyThread extends Thread {
public void run() {
if (Thread.currentThread() != this) {
System.out.println("Wrapped into a separate thread");
start();
} else {
System.out.println("MyThread run as expected");
}
}
public static void main(String[] args) {
new Thread(new MyThread ()).start();
}
}
為了使名稱更容易混淆,讓我們來看另一個示例:
public class MyJPanel extends JPanel implements Runnable {
public void run() {
System.out.println("Hello MyJPanel");
}
public static void main(String[] args) {
new Thread(new MyJPanel()).start();
}
}
第一個調用(如果它將是run())將在當前線程中執行,而第二個調用將創建一個新線程,該線程將運行您的Runnable的run()方法。
在第二篇中,您將創建一個不包含在變量中的新線程,並啟動該新線程。 t2保持不變。
在第一個中,您創建t1並開始...
我認為第二是沒有意義的
每當您的班級需要擴展另一個班級時,請使用Runnable。
而且Runnable界面僅包含run方法而無法啟動。
假設MyThread
僅實現Runnable
接口,第二個代碼段就是使用的正確模式。 Thread.start()
鏈接到本機方法,該方法將產生新線程。 然后,它將調用自己的run()
,后者將在其實例Runnable
變量上調用run()
。 在第二個代碼段中,這將是MyThread
的實例,即Runnable
。
根據您提供的信息,第一個代碼段將不會編譯,除非:
start
方法。 在這種情況下,您的代碼將不會啟動新線程,並且您將僅按照MyThread.start()
定義的當前線程進行操作。 Thread
並實現了Runnable
。 如果是這種情況,則Runnable
接口是多余的,因為Thread
也會實現此接口。 另外,如果要覆蓋start
方法,則應格外小心,因為如果要使用新線程,則需要對super進行調用。 至少由於這個原因,最好只讓類實現Runnable
而不擴展Thread
。 此外,如果僅實現Runnable
,則最好不要在名稱中使用Thread
一詞。 MyThread t1 =新的MyThread(); t1.start();
將是編譯時異常
MyThread t2 =新的MyThread(); 新線程(t2).start();
會正常工作。可運行接口沒有啟動方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.