[英]How to use wait() and notifyAll() to communicate between a GUI class and logic thread
[英]How to use wait() and notifyAll() to run thread one by one?
我写了一个House类,它有四个同步方法。 我编写了四个线程,并希望它们一个一运行。 但是只有第一和第二跑了,其他没有?
public class House {
private boolean hasFoundation = false;
private boolean hasFrame = false;
private boolean hasWall = false;
private boolean hasRoof = false;
public synchronized void buildFoundation() {
hasFoundation = true;
System.out.println("foundation Ok");
notifyAll();
}
public synchronized void buildFrame() throws InterruptedException {
if (!hasFoundation) {
wait();
} else {
hasFrame = true;
System.out.println("frame ok");
notifyAll();
}
}
public synchronized void buildWall() throws InterruptedException {
if (!hasFrame) {
wait();
} else {
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
}
public synchronized void buildRoof() throws InterruptedException {
if (!hasWall) {
wait();
} else {
hasRoof = true;
System.out.println("roof ok");
notifyAll();
}
}
}
public class BuildAHouse {
public static void main(String[] args) {
House house = new House();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new FoundationTeam(house));
exec.execute(new WallTeam(house));
exec.execute(new RoofTeam(house));
exec.execute(new FrameTeam(house));
exec.shutdown();
}
}
当运行main()时,结果只是:Foundation ok frame ok
其他两个线程未运行! 为什么?
... Team类是这样的:
public class FoundationTeam implements Runnable {
private House house;
public FoundationTeam(House house) {
this.house = house;
}
@Override
public void run() {
house.buildFoundation();
}
}
这只是一个演示,我想知道如何使用wait()和notifyAll()。
请解决这个问题好吗? 这只是我想要做的所有事情的一部分。 请告诉我为什么它不起作用,以及如何解决?
当调用wait()时,该对象将不会被释放? 和其他线程不能调用其他同步方法?
如果您的方法确实使用了wait(),则它将不会在else
块中运行任何else
注意:wait()可能会虚假唤醒,建议使用while循环。
其他两个线程未运行! 为什么?
正如@Peter提到的那样,您已经弄清楚了,您需要while(!boolean)
wait循环周围使用while(!boolean)
循环。 这出于两个原因是必要的。
正如Peter所提到的, wait()
可能由于虚假唤醒而不是正确的notify()
调用而返回。 您需要确保实际上正在设置您要等待的条件,然后循环并再次调用wait()
如果尚未设置wait()
。
但是,就您而言,它与虚假唤醒无关,而与程序编写方式有关。 因为您有一个synchronized
对象( House
对象),所以当您调用notifyAll()
所有团队线程都被唤醒。 调用buildFoundation()
方法时,它将hasFoundation
设置为true并唤醒所有团队。 但是只有框架团队才能真正开始工作-其他团队需要循环并等待更多时间,直到布尔值设置为true。
您可以将代码更改为对每个步骤使用不同的锁,这将使代码易于使用,尽管您仍然需要while
循环。
最后,正如您已经知道的那样, if ... else ...
模式毫无意义,因为当团队等待时,当他们被通知时,他们的构建方法将返回,因为其他东西在else
。
是工作!
public synchronized void buildWall() throws InterruptedException {
while (!hasFrame) {
wait();
}
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
添加“ while()”,但是我不知道为什么!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.