4

所以我正在开发这个模拟一天工作的程序,每个工人都是自己的线程。我正在尝试实施工人参加会议的会议,但会议要等到应该参加会议的每个人都到达后才开始。所以我有这种参加会议的方法。

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

worker 参数是扩展 Thread 的 Employee 类的实例,this.cdStart 是 CountDownLatch。但是,在四名员工的会议上运行此程序时,似乎只有一名员工能够进入,减少计数,然后点击 await() 调用。其他工作线程似乎都无法进入它。我确实注意到许多在线使用示例将 CountDownLock 对象传递给线程本身来处理。有没有理由为什么这不起作用?

4

1 回答 1

4

我假设您在 Employee Thread 对象中传递了一个线程。该单个线程将无限期地等待,直到 N 方到达(除了 Employee 线程之外,每个 Employee 实例都需要一个单独的线程)。这意味着,如果只有一个线程不断通过员工/线程,您将永远不会有超过一个员工在会议上等待。

相反,该线程最多应该向员工线程发出信号以参加会议。

您应该在会议类中有闩锁,并让他们在该闩锁上等待。这也需要对其工作方式进行轻微重组。

您将 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 的工作方式更适合您尝试做的事情,然后 Meeting 类看起来像

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

     public void waitForAllOthersToArrive(){
         barrier.await(); //when await() is called numberOfEmployees then all waiting threads will awake
     }
 }
于 2012-04-18T16:57:28.897 回答