首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用wait()发出;

使用wait()发出;
EN

Stack Overflow用户
提问于 2013-02-23 15:59:03
回答 2查看 200关注 0票数 1

我目前有这个run方法,我希望有3个独立的线程来访问,并等待另一个线程通知。

代码语言:javascript
复制
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时,第一个线程会等待,另外两个线程不能做任何事情,因为第一个线程在方法上有一个锁。所以我的问题是,如何才能让三个独立的线程可以同时访问这个方法并等待呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-23 16:05:07

要使用wait(),您必须使用own the monitorYou acquire the ownership by using synchronize。在你的例子中是synchronize(this)

但是,要阻止3个线程并从第4个线程释放它们,您可以使用Perception提到的java.util.concurrent.CyclicBarrierjava.util.concurrent.CountDownLatch

下面是一个带有CyclicBarrier的版本:

代码语言:javascript
复制
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 );
   }
}

输出:

代码语言:javascript
复制
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的版本:

代码语言:javascript
复制
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 );
   }
}

输出:

代码语言:javascript
复制
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!
票数 3
EN

Stack Overflow用户

发布于 2013-02-23 16:08:19

当第一个线程等待时,它会释放锁。这样其他线程就可以获得锁。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15038444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档