2012-04-18 4 views
4

私は仕事で1日をシミュレートするこのプログラムに取り組んでおり、各作業者はそれぞれのスレッドです。私は、労働者が会議に出席する会議を実施しようとしていますが、会議に参加するはずの人が到着するまで会議は開始しません。だから、私はこの会議に出席する方法を持っています。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 

スレッドを拡張しthis.cdStartがたCountDownLatchあるEmployeeクラスのインスタンスであるワーカー・パラメータ。しかし、これを4人の従業員の会議で実行すると、1人の従業員だけが入り込んでカウントを減らし、await()コールを打つことができます。他のワーカースレッドのどれもそれに入ることができないようです。私は、多くのオンライン使用例がCountDownLockオブジェクトをスレッド自体に渡して処理することに気付きました。これが代わりに機能しない理由はありますか?

+2

のように見えるのでしょうか? –

+0

私は、主にEmployeeクラスを担当するチームメイトを抱えており、従業員が実際にアクティブな会議に出席しているか待機しているかどうかを含めて、会議全体でEmployeeの状態を更新したいと述べました。これがmeetingWait()メソッドとmeetingStart()メソッドの目的です。 –

答えて

4

私はあなたがEmployee Threadオブジェクトに1つのスレッドを渡していると仮定しています。 N個の当事者が到着するまで、その単一のスレッドは無期限に待機します(Employeeスレッド以外の各Employeeインスタンスに対して個別のスレッドが必要です)。これは、1つのスレッドだけが従業員/スレッドを継続的に通過している場合、会議で待っている従業員が2人以上になることはありません。

このスレッドは、せいぜい会議に出席するために従業員スレッドに通知する必要があります。

ラッチを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(); 
    } 
    } 

私がこれについて示唆しているのは、シリルバリアです。あなたがそれを使用して再されないものの、CyclicBarrierをが動作する方法は、あなたが何をしようとして、より良いフィットし、会議のクラスは、worker.meetingWait()は何をするん

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)は、通常、待機スレッドとカウントダウンスレッドを別々にすることを意味します。 –

+0

おそらく私はこの質問にこれを言及していたはずです。ミーティングのコンストラクタは、参加する従業員のリストを取得します。ルームが利用可能になると、ルームは会議を受け取り、会議オブジェクトのstartMeeting()メソッドを呼び出します。このメソッドは、リスト内のすべてのEmployeeオブジェクトのmeetingRequest()メソッドを呼び出します。 @DavidHarkness CountDownLatchを使用するのは、各会議で新しい会議オブジェクトが使用されるためです。ミーティングオブジェクトは多かれ少なかれ1つのイベントをカプセル化するため、CyclicBarrierよりCountDownLatchを使用するほうが適しているようです。 –

+0

@ grg-n-sox [OK]をクリックします。なぜ、あなたのプログラムには従業員が1人しかいないのですか?あなたが持っている必要があるのは、 'await()'を持つメソッドを呼び出すEmployeeスレッドです。従業員スレッドは、会議を開始しているメインスレッドではなく、中断されます。ミーティングを開始しているこのメインスレッドは、ミーティングの開始を待つためにスレッドに通知する必要があります。スレッドの開始は、他のすべてのスレッドがミーティングで待機することです。明らかに、別の方法である必要があります。 –