2012-04-18 47 views
4

所以我正在研究這個模擬一天工作的程序,每個工人都是自己的線程。我試圖在員工參加會議的地方實施會議,但會議直到會議開始時纔會開始。所以我有參加會議的這種方法。Java的CountDownLatch可以從被動類而不是線程中使用嗎?

public void attendMeeting(Employee worker){ 
    this.cdStart.countDown(); 
    worker.meetingWait(); 
    try { 
     this.cdStart.await(); 
     worker.meetingStart(this.length); 
     if(this.attendees.get(0).equals(worker)){ 
      this.room.exit(); 
     } // end if 

    } // end try 
    catch (InterruptedException err) { 
     // Do Nothing 

    } // end catch 

} // end method attendMeeting 

工人蔘數是擴展Thread和this.cdStart是CountDownLatch Employee類的實例。但是,當通過四名員工開會時,只有一名員工似乎能夠進入,減少計數,然後執行await()調用。沒有其他工作線程似乎能夠輸入它。我注意到很多在線的使用示例都將CountDownLock對象傳遞給線程本身來處理。有沒有原因爲什麼這不會起作用呢?

+2

是什麼worker.meetingWait()呢? – 2012-04-18 16:42:46

+0

我有一個主要負責員工班級的隊友,並提到他希望在整個會議期間更新員工狀態,包括員工是否真正參加活動會議或只是在等待。這就是meetingWait()和meetingStart()方法的用處。 – 2012-04-18 18:21:03

回答

4

我假設你在一個Employee Thread對象中有一個線程傳遞。該單個線程將無限期地等待,直到N個參與方到達爲止(您需要爲員工線程外的每個員工實例創建一個單獨的線程)。這意味着如果只有一個線程持續通過員工/線程,您將永遠不會得到多於一名員工在會議中等待。

這個線程應該最好發信號通知員工線程參加會議。

您應該在Meeting類中鎖定閂鎖並讓它們等待該閂鎖。這也需要對其工作方式進行輕微的重組。

您將Meeting實例傳遞給Employee以讓該線程等待。

public Employee extends Thread{ 

    //define this at some point whether in constructor or a 
    //means of notifying the thread to attend the meeting 
     private Meeting meeting; 

     public void run(){ 
      //do some stuff until this employee is ready to go to a meeting 

     meeting.waitForAllOthersToArrive(); 
     } 

    } 

    public class Meeting{ 
    CountDownLatch latch = new CountDownLatch(numberOfEmployees); 

    public void waitForAllOthersToArrive(){ 
     latch.countDown(); 
     latch.await(); 
    } 
    } 

然而,我建議這是一個CylicBarrier。雖然你不會使用它進行重新的的CyclicBarrier的工作方式更符合你想要做什麼,會議類會再像

public class Meeting{ 
    CylicBarrier barrier = new CylicBarrier(numberOfEmployees); 

    public void waitForAllOthersToArrive(){ 
     barrier.await(); //when await() is called numberOfEmployees then all waiting threads will awake 
    } 
} 
+1

+1 ['CyclicBarrier'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html)肯定更適合。 ['CountDownLatch'](http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html)通常意味着單獨的等待與倒計時線程。 – 2012-04-18 18:02:59

+0

我可能應該在問題中提到這一點。會議的構造函數列出了要參加的員工名單。當房間變得可用時,會議室召開會議,並在會議對象上調用startMeeting()方法,該方法又調用列表中所有Employee對象的meetingRequest()方法。 @DavidHarkness使用CountDownLatch的原因是因爲每個會議都使用一個新的會議對象。由於會議對象或多或少封裝了單個事件,因此使用CountDownLatch似乎比CyclicBarrier更合適。 – 2012-04-18 18:24:40

+0

@ grg-n-sox好吧,你明白爲什麼你的程序只會有一個Employee到達嗎?你需要的是Employee線程調用具有latch'await()'的方法。然後,員工線程將被暫停,而不是開始會議的主線程。因此,開始會議的這個主線程應該通知線程等待會議開始,您擁有的是啓動的線程正在等待所有其他線程等待會議,顯然它必須是相反的方式。 – 2012-04-18 18:28:18

相關問題