我目前有这个run方法,我希望有3个独立的线程来访问,并等待另一个线程通知。
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时,第一个线程会等待,另外两个线程不能做任何事情,因为第一个线程在方法上有一个锁。所以我的问题是,如何才能让三个独立的线程可以同时访问这个方法并等待呢?
发布于 2013-02-23 16:05:07
要使用wait(),您必须使用own the monitor。You acquire the ownership by using synchronize。在你的例子中是synchronize(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-23 16:08:19
当第一个线程等待时,它会释放锁。这样其他线程就可以获得锁。
https://stackoverflow.com/questions/15038444
复制相似问题