2013-07-14 46 views
0

我正在玩Java中的線程,我對join()方法有疑問。 假設我有一個擴展Thread的SampleClass。我在main中實例化了一些新的線程,但是我想要使用join()順序完成線程的工作。是否可以在一次調用中調用Thread start()和join()?

public static void main(String[] args) { 
    for(int i=0; i<5; i++){ 
     new SampleClass().start(); 
    } 
} 

是否可以立即調用join()方法? ...這樣的事:

new SampleClass().start().join(); 

還是有另一種方法來使用? ......像這樣也許:

new SampleClass().start(); 
try{Thread.currentThread().join();}catch(InterruptedException e){...} 

非常感謝您

+0

嗯......這個問題可以通過花2分鐘閱讀javadocs來回答。 –

+0

我已經看過這裏 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29 但我還沒有找到任何有用的信息給我。 – Emanuele

回答

1
new SampleClass().start().join(); This is wrong. 

您可以通過

SampleClass samClass = new SampleClass(); 
    samClass.start(); 
    samClass.join() 

上面的代碼實現類似的事情都會有你想要的效果相同。

現在你的問題是按順序運行線程。 在大多數這些 的情況下,你不需要線程順序執行(但是有一些情況)。 那麼如果你不得不。

然後你就可以像這樣

Thread t1 = .. 
    Thread t2 = .. 

    t1.start(); 
    t1.join(); 
    t2.start(); // t2 will start only when t1 dies 
    t2.join(); // 
    t3.start(); // t3 will start only when t2 dies.. 

但上面的方法並不好。因爲要啓動其他線程,需要先前線程 。在實踐中,我們應該考慮將線程創建爲昂貴的操作 並嘗試重用

真正的問題往往就是這樣,你必須執行的任務T1,T2,T3,T4 順序,但在不同的線程T1 & & T3必須在一個線程運行,T2和T4 必須在另一個運行。 所以在這裏我們可以使用兩個線程而不是4個。 線程1將上 即

Thread1 -> T1 
Thread2 -> T2 
Thread1 -> T3 
Thread2 -> T4 

運行T1,然後線程2將運行T2,然後線程1將運行T3等所有任務將被順序地但僅使用2個線程執行。

你能解決這個問題,像下面

Thread1 ->run { 
    while(canIrun) { 
    executeTask(taskQueue1.next()); 
    notifyThread2(); 
    waitForThread2Signal(); 
    } 
    } 

    Thread2 -.run { 
    while(canIrun) { 
    waitForThread1Signal(); 
    executeTask(taskQueue2.next()); 
    notifyThread1(); 
    } 
    } 

等待和通知方法可以很容易使用的CyclicBarrier來實現。

+0

謝謝你的時間,寫一些例子並給出一些解釋。 :-) – Emanuele

1

是否可以立即調用join()方法?

不,它不是start()返回void。你不能以這種方式鏈接這些方法。你需要在Thread對象上調用join()

+0

好的,謝謝,所以鏈接是不可能的。假設線程被實例化了,怎麼可能(如果可能)調用join()方法呢? Thread.currentThread()join()方法。似乎工作,但不是我所期待的。 第一個線程實例被創建,它完成了工作,但是沒有其他事情發生(其他線程沒有像FOR只運行一次那樣被實例化)。 – Emanuele

0

方法的開始屬於Thread類。這將是這樣做的:

Thread thread = new Thread(someRunnableTask); 
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object. 
Thread ourOriginalThreadPointer = thread.start(); 
//Hence this variable references to nothing, no method can be called. 
ourOriginalThreadPointer.join() 
+0

Err,這是*問題,*不是答案。問題是'start()'返回void,所以你的代碼不會被編譯,只不過是OP的代碼。 -1 – EJP

+0

它應該解釋爲什麼它不會爲那些要求知道它如何工作的人編譯。學着閱讀。我說那裏不會編譯。 – 2013-07-15 09:16:56

0

instanciated線程不需要是匿名的。你可以這樣做:

public static void main(String[] args) { 
    for(int i=0; i<5; i++){ 
     SampleClass sc = new SampleClass(); 
     sc.start(); 
     try { 
      sc.join(); 
     } catch (InterruptedException e) { 
     } 
    } 
} 
1

會是什麼意思?你可以通過調用run()來獲得相同的效果,沒有開銷。

+1

+1 - 好點。開始一個線程,並立即加入它,否定了你可能從首先使用線程獲得的任何好處。 –

相關問題