2011-03-31 57 views
2

民間,Java - java線程可以多次啓動嗎?

我知道這個問題之前已經問過,雖然間接地。但它沒有回答我的疑問。
問:Is it legal to call the start method twice on the same Thread?

spec

這是從來沒有的法律,以啓動一個線程 不止一次。特別是,一旦 完成執行, 線程可能無法重新啓動。

我同意。但是我的代碼並沒有拋出一個IllegalThreadStateException它預計會執行下面的程序。

public class Tester extends Thread { 
     public void run() { 
      System.out.print("run"); 
     } 
     public static void main(String[] args) { 
      Tester thread = new Tester(); 
      new Thread(thread).start(); 
      new Thread(thread).start(); 
     } 
    }  

Q.1)我在Eclipse中運行了上面的代碼。在這裏,因爲我試圖在同一個實例上啓動一個新線程,所以預計會拋出一個IllegalThreadStateException。但事實並非如此。

爲什麼?

Q.2)如果我們確實在同一個實例上啓動了一個新線程,它會有什麼危害?

任何幫助將不勝感激!

+2

我不認爲這只是(它)會造成什麼危害的問題。我認爲這更多是一個毫無意義的問題。啓動一個已經運行的線程是什麼意思?你可以開一輛已經開着的汽車嗎?這個想法根本沒有意義。 – 2011-03-31 14:19:46

回答

6

首先,您在兩個不同的線程對象上調用,即:

new Thread(thread).start(); 
new Thread(thread).start(); 

您在兩個不同的實例調用start方法。出於這個原因,你沒有得到例外。

嘗試用以下命令獲取例外

thread.start(); 
thread.start(); 

關於第二個問題。你可以在這裏得到了答案:Why can't we call the start method twice on a same instance of the Thread object?

這是由我:)幸好問

+0

謝謝。 Q.2有什麼想法? – 2011-03-31 14:09:41

9

您不是在同一個實例上調用start()。每次你使用新的你正在創建一個不同的實例。因此調用start()沒有問題。

如果你這樣做:

Thread t = new Thread(thread); 
t.start(); 
t.start(); 

那麼你可能有問題。

+0

+1 ....謝謝!我清除了。 Q.2呢? – 2011-03-31 14:09:14

1

Java線程調用可以開始了不止一次?

您可以根據需要隨時參與start()。但是,如果您在相同的線程上多次調用IllegalThreadStateException,則會發生IllegalThreadStateException。

Q.1)我在Eclipse中運行了上面的代碼。在這裏,因爲我試圖在同一個實例上啓動一個新線程,所以預計會拋出IllegalThreadStateException異常。但事實並非如此。

那是因爲你創建了三個不同的線程。一個是測試人員,另一個是測試人員。

Q.2)如果我們確實在同一個實例上啓動了一個新線程,它會有什麼危害?

除了造成混淆,沒有。你不應該這樣做。測試者應該實現Runnable。

1

Q.1)我在Eclipse中運行了上面的代碼。在這裏,因爲我試圖在同一個實例上啓動一個新線程,所以預計會拋出IllegalThreadStateException異常。但事實並非如此。

你不是在同一個實例上調用start()。

new Thread(thread).start(); 

上面的語句是一樣的

new Thread((Runnable)thread).start(); 
+0

我冒昧地格式化你的答案。我希望這是好的。 – 2011-03-31 14:08:31

+1

@彼得:謝謝 – 2011-03-31 14:09:14

0

在這裏,我們看到爲什麼執行人賺那麼多的意義。

典型的慣用Java會說你根本不應該運行你自己的線程;創建一個執行器服務,並讓它管理這些線程。您只需創建Runnable實例並將其傳遞給執行程序服務;您可以隨時隨地調用Runnable的run()方法,無論何時何地有意義,並且您在此時不必關心線程管理。

擴展主題也是一筆交易;在Java中擴展超類很昂貴(因爲你得到一個超類,就是這樣)。但是,您可以根據需要擴展多個接口,因此Runnable也爲您提供了更強大的對象層次結構。

+0

這個答案與我的問題有什麼關係? – 2011-03-31 14:13:00

+1

好吧,國際海事組織,你的問題的答案是非常明顯的表面上:不,在同一個線程實例上調用start()兩次是不合法的。 第一個問題使用了一個無效的假設(你不是在同一個Thread實例上調用兩次start(),而是創建了兩個單獨的Thread實例)。 第二個問題沒有實際意義,因爲Thread的定義意味着你不能啓動兩次;你會得到一個非法的狀態。 所以**我做的是試圖想想你可能試圖達到的任務。使用runnables意味着你可以**看起來**運行兩次。 – 2011-03-31 15:07:20

0

由於大部分答案都涵蓋了Q1,因此我想集中討論Q2,即「如果我們確實在同一個實例上啓動了新線程,它會做什麼?」第一個要考慮的問題是第二次調用線程啓動方法的時候,第一個線程正在執行(情況:1)還是第一個線程執行完成後(情況2)

case1:爲了識別被啓動的線程並執行唯一的方法是用於創建的線程對象,所以如果有機會第二次調用start()方法,那麼將假設其他線程被創建並執行,但是如果我們想要更改/操作在特定實例上執行的多個線程中的特定線程,我們將如何單獨識別它們,因此完全不可能,因此唯一標識正在運行的線程並在它上面工作java不允許調用start ()方法多次。

案例2:如果已經運行的線程完成,java爲什麼不讓我們多次調用start()方法? 在java中,一旦對象的範圍結束,它需要被垃圾回收,所以如果線程對象也發生這種情況,但是如果有一個設施可以多次調用start方法,則java env不應該允許GC發生對線程對象認爲可能還有第二次使用這個線程對象,並且這個線程對象將永遠在堆中(或某個地方)而不會得到GC。

所以考慮上面兩個原因,他們可能只對一個線程對象調用start()方法做了一次限制。