2011-06-28 110 views
2

我得到了一堆執行計算的線程。他們使用CyclicBarrier「同步」。當任意線程的run()方法結束時,我想要全部其他線程退出以及一旦他們在下一次屏障上呼叫await()Java - 正常退出線程

到目前爲止,我嘗試過的所有事情都會掛在await()調用中,或者導致屏障破裂。有小費嗎?

編輯:這裏的(基本)代碼:

public MyClass implements Runnable { 
    public void run() { 
     while (true) { 
      if (someCondition) { 
       // quit other threads when they call await() 
       return; 
      } 
      barrier.await(); 
    } 
} 
+0

顯示代碼,這很難回答。 – Woot4Moo

+0

@ Woot4Moo:完成... – ryyst

+0

@ryyst,我不認爲CyclicBarrier會做你想做的。 –

回答

3

復位()會喚醒所有等待的線程與拋出的異常

然後你可以使用的await因爲如此

private static volatile boolean shouldStop=false; 

public void run() { 
    try{ 
     while (true) { 
      if (someCondition) { 
       // quit other threads when they call await() 
       return; 
      } 
      try{ 
       if(shouldStop)return; 
       barrier.await(); 
      }catch(BrokenBarrierException e){ 
       //someone stopped 
       return; 
      } 
     } 
    }finally{ 
     shouldStop =true; 
     barrier.reset(); 
    } 
} 

你也可以撥打if(shouldStop)查詢方法

+0

如果由於某些其他原因導致屏障中斷,該怎麼辦?你的解決方案實際上就像我目前已經實現了這一點,但我對此並不滿意。 – ryyst

+0

@ryyst,你不開心嗎?如果不知道這一點,很難提出替代方案。 –

+0

做一個額外的檢查在捕獲,但如果障礙被打破,需要有一些額外的同步之前,你可以繼續和破碎髮生只有當你使用超時和中斷(或障礙動作引發異常) –

0

從聲音其中你可能想要一個CountDownLatch。假設你知道線程/參與者的數量,您只需創建一個很多,然後當你的線程完成倒計時,等待鎖:

final int workers = … 
final CountDownLatch latch = new CountDownLatch(workers); 

void doSomething() throws InterruptedException { 
    … 
    latch.countDown(); 
    latch.await(); // blocks, throws InterruptedException 
} 

相比CyclicBarrierCountDownLatch不能重複使用,只能使用它曾經。但是,它確實將等待和釋放問題分開,因此您可以使用另一個允許線程通過的線程。

所有這一切說,如果你需要以上代碼CyclicBarrier略有變化應該工作:

final int workers = … 
final CyclicBarrier barrier = new CyclicBarrier(workers); 

void doSomething() throws InterruptedException, BrokenBarrierException { 
    … 
    latch.await(); // blocks, throws InterruptedException, BrokenBarrierException 
} 

但是,如果任何線程中斷或barrier.reset()被稱爲然後屏障被打破,拋出異常。