4 Stimmen

Kann Java's CountDownLatch von einer passiven Klasse anstatt von einem Thread verwendet werden?

Ich arbeite also an diesem Programm, das einen Arbeitstag simuliert, und jeder Arbeiter ist sein eigener Thread. Ich versuche, Besprechungen zu implementieren, bei denen die Arbeiter an Besprechungen teilnehmen, aber die Besprechungen beginnen erst, wenn alle, die an der Besprechung teilnehmen sollen, eingetroffen sind. Ich habe also diese Methode für die Teilnahme an der Besprechung.

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

Der Worker-Parameter ist eine Instanz der Employee-Klasse, die Thread erweitert, und this.cdStart ist das CountDownLatch. Bei einer Besprechung mit vier Mitarbeitern scheint jedoch nur ein Mitarbeiter in der Lage zu sein, die Zählung zu dekrementieren und den Aufruf await() auszuführen. Keiner der anderen Worker-Threads scheint in der Lage zu sein, die Sitzung zu betreten. Ich habe bemerkt, dass viele der Online-Beispiele der Verwendung übergeben das CountDownLock-Objekt an die Threads selbst zu behandeln. Gibt es einen Grund, warum dies nicht stattdessen funktionieren würde?

4voto

John Vint Punkte 38604

Ich gehe davon aus, dass Sie einen einzelnen Thread in einem Employee-Thread-Objekt übergeben. Dieser einzelne Thread wartet auf unbestimmte Zeit, bis die Anzahl N der Parteien eintrifft (Sie benötigen einen eigenen Thread für jede Employee-Instanz neben dem Employee-Thread). Das bedeutet, dass, wenn nur ein Thread den Employee/Thread kontinuierlich weitergibt, nie mehr als ein Employee auf das Treffen warten wird.

Dieser Thread sollte stattdessen bestenfalls den Arbeitnehmer-Threads signalisieren, an der Sitzung teilzunehmen.

Sie sollten den Riegel in der Besprechungsklasse haben und sie auf diesen Riegel warten lassen. Dies erfordert auch eine leichte Umstrukturierung der Arbeitsweise.

Sie übergeben die Besprechungsinstanz an den Mitarbeiter, damit dieser Thread wartet.

    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();
     } 
   }  

Was ich allerdings vorschlagen würde, ist eine CylicBarrier. Obwohl Sie nicht wieder mit ihm, die Art und Weise der CyclicBarrier funktioniert passt besser, was Sie versuchen zu tun, die Sitzung Klasse würde dann aussehen wie

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X