1

私は現在、3つの別々のスレッドがアクセスし、別のスレッドが通知するのを待つこのrunメソッドを持っています。

public void run(){
   try {
      System.out.println(this.name + " waits on the table...");
      /// waits for agent to signal that new ingredients have been passed out
      wait();
   } catch(InterruptedException ex) {
      Thread.currentThread().interrupt();
   }
   System.out.println(this.name + " stops waiting and checks the table...");
   checkTable();
}

現在、これjava.lang.IllegalMonitorStateExceptionはメソッドでsynchroizeを使用することで解決できるをスローします。問題は、synchroizeを使用すると、最初のスレッドが待機し、最初のスレッドがメソッドをロックしているため、他の2つのスレッドが何もできないことです。だから私の質問は、3つの別々のスレッドがこのメソッドにアクセスして同時に待機できるようにするにはどうすればよいですか?

4

2 に答える 2

3

使用するには、モニターwait()を所有している必要があります。 を使用して所有権を取得します。あなたの場合。synchronizesynchronize(this)

ただし、3つのスレッドをブロックし、4番目のスレッドから解放するには、Perceptionが言及しjava.util.concurrent.CyclicBarrierたようにまたはを使用できます。java.util.concurrent.CountDownLatch

CyclicBarrierを使用したバージョンは次のとおりです。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class RendezVous extends Thread {

   private final CyclicBarrier _barrier;

   RendezVous( String name, CyclicBarrier barrier ) {
      super( name );

      _barrier = barrier;
      setDaemon( true );
      start();
   }

   @Override public void run() {
      System.out.println( getName() + " waits for counterparts..." );
      try { _barrier.await(); }
      catch( InterruptedException | BrokenBarrierException x ) {
         x.printStackTrace(); }
      System.out.println( getName() + " has reached its rendez-vous!");
   }

   public static void main( String[] args ) throws InterruptedException {
      CyclicBarrier barrier = new CyclicBarrier( 4 );
      new RendezVous( "Rdvz 1", barrier ); Thread.sleep(  1000L );
      new RendezVous( "Rdvz 2", barrier ); Thread.sleep(  1000L );
      new RendezVous( "Rdvz 3", barrier ); Thread.sleep(  1000L );
      new RendezVous( "Rdvz 4", barrier ); Thread.sleep( 10000L );
   }
}

出力:

Rdvz 1 waits for counterparts...
Rdvz 2 waits for counterparts...
Rdvz 3 waits for counterparts...
Rdvz 4 waits for counterparts...
Rdvz 4 has reached its rendez-vous!
Rdvz 1 has reached its rendez-vous!
Rdvz 2 has reached its rendez-vous!
Rdvz 3 has reached its rendez-vous!

そして、CountDownLatchを使用したバージョン:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo extends Thread {

   private final CountDownLatch _cdl;

   CountDownLatchDemo( String name, CountDownLatch cdl ) {
      super( name );

      _cdl = cdl;
      setDaemon( true );
      start();
   }

   @Override public void run() {
      System.out.println( getName() + " waits for counterparts..." );
      try {
         _cdl.countDown();
         _cdl.await();
      }
      catch( InterruptedException x ) {
         x.printStackTrace(); }
      System.out.println( getName() + " has reached its rendez-vous!");
   }

   public static void main( String[] args ) throws InterruptedException {
      CountDownLatch cdl = new CountDownLatch( 4 );
      new CountDownLatchDemo( "Rdvz 1", cdl ); Thread.sleep(  1000L );
      new CountDownLatchDemo( "Rdvz 2", cdl ); Thread.sleep(  1000L );
      new CountDownLatchDemo( "Rdvz 3", cdl ); Thread.sleep(  1000L );
      new CountDownLatchDemo( "Rdvz 4", cdl ); Thread.sleep( 10000L );
   }
}

出力:

Rdvz 1 waits for counterparts...
Rdvz 2 waits for counterparts...
Rdvz 3 waits for counterparts...
Rdvz 4 waits for counterparts...
Rdvz 4 has reached its rendez-vous!
Rdvz 1 has reached its rendez-vous!
Rdvz 2 has reached its rendez-vous!
Rdvz 3 has reached its rendez-vous!
于 2013-02-23T08:05:07.217 に答える
0

最初のスレッドが待機状態になると、ロックが解除されます。したがって、他のスレッドがロックを取得できます

于 2013-02-23T08:08:18.953 に答える