2012-04-18 5 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 

worker 매개 변수는 Thread를 확장하는 Employee 클래스의 인스턴스이고 this.cdStart는 CountDownLatch입니다. 그러나 4 명의 직원과의 회의에서이 작업을 실행하면 단 한 명의 직원 만 들어 와서 카운트를 줄이고 await() 호출을 수행 할 수 있습니다. 다른 작업자 스레드 중 아무 것도 입력 할 수없는 것 같습니다. 나는 많은 온라인 예제를 사용하여 CountDownLock 객체를 스레드 자체에 전달하여 처리 할 수 ​​있음을 확인했습니다. 이것이 대신 작동하지 않는 이유가 있습니까?

+2

과 같을 것이다? –

+0

저는 주로 Employee 클래스에 대한 책임이있는 팀원이 있습니다. 그리고 직원이 실제로 활성 미팅에 참석 중이거나 대기중인 경우를 포함하여 미팅 전반에 걸쳐 직원 상태를 업데이트하려고한다고 언급했습니다. 이것이 바로 meetingWait() 및 meetingStart() 메서드에 대한 것입니다. –

답변

4

Employee Thread 개체에 단일 스레드 패스가 있다고 가정합니다. 이 단일 스레드는 N 개의 참여자가 도착할 때까지 무기한 대기합니다 (Employee 스레드 이외의 각 Employee 인스턴스에 대해 개별 스레드가 필요함). 즉, 하나의 스레드 만 지속적으로 Employee/Thread를 통과하면 더 이상 한 명의 직원이 회의에서 대기하지 않습니다.

대신이 스레드는 회의에 참석하기 위해 직원 스레드에 신호해야합니다.

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가 작동하는 방식은 당신이 뭘하려는 건지 잘 맞는, 회의 클래스는 다음 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를 사용하는 이유는 각 모임에 새 모임 개체가 사용되기 때문입니다. 모임 개체가 단일 이벤트를 다소 캡슐화하기 때문에 CyclicBarrier보다 CountDownLatch를 사용하는 것이 더 적합 할 것으로 보입니다. –

+0

@ grg-n-sox 좋아, 왜 프로그램에 한 명의 직원 만 도착하는지 알겠습니까? 필요한 것은 래치'await()'가있는 메소드를 호출하는 Employee 스레드입니다. Employee 스레드는 회의를 시작하는 주 스레드가 아닌 일시 중단됩니다. 그래서 회의를 시작하는이 메인 스레드는 회의 시작을 기다리는 스레드에게 알리고, 다른 스레드가 회의를 기다리는 동안 스레드 시작을 기다리고 있습니다. 분명히 다른 방법이 있어야합니다. . –