如何使用 wait() 和 notifyAll() 到 运行 一个个线程?
How to use wait() and notifyAll() to run thread one by one?
我写了一个Houseclass,它有四个synchronized方法。
我写了四个线程,并希望它们 运行 一个接一个。但只有第一个和第二个有 运行,另一个没有?
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()时,结果只是:
基础好
框架正常
另外两个线程没有运行!为什么?
...团队 class 喜欢这样:
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
块中的任何内容
注意:wait() 可能会虚假唤醒,建议使用 while 循环。
成功了!
public synchronized void buildWall() throws InterruptedException {
while (!hasFrame) {
wait();
}
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
添加"while()",但我已经不知道为什么了!
the other two thread havn't run! why?
正如@Peter 提到的那样,您已经发现,您需要 while(!boolean)
循环您的等待循环。出于几个原因,这是必要的。
正如 Peter 提到的那样,wait()
可能 return 因为虚假唤醒而不是正确的 notify()
调用。您需要确保您正在等待的条件实际上已经设置,然后循环并再次调用 wait()
如果没有。
但是,在您的情况下,与虚假唤醒无关,而与您的程序编写方式有关。因为您有一个 synchronized
对象(House
对象),所以当您调用 notifyAll()
时,所有团队线程都会被唤醒。当调用 buildFoundation()
方法时,它会将 hasFoundation
设置为 true 并唤醒所有团队。但只有框架团队才能真正开始工作——其他团队需要循环并等待一段时间,直到他们的布尔值设置为 true。
您可以更改代码以对每个步骤使用 不同的 锁,这将使代码更容易理解,尽管您仍然需要 while
循环。
最后,正如您已经发现的那样,您的 if ... else ...
模式没有任何意义,因为当团队等待时,当他们收到通知时,他们的构建方法只会 return 因为另一个东西在 else
.
我写了一个Houseclass,它有四个synchronized方法。 我写了四个线程,并希望它们 运行 一个接一个。但只有第一个和第二个有 运行,另一个没有?
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()时,结果只是: 基础好 框架正常
另外两个线程没有运行!为什么?
...团队 class 喜欢这样:
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
块中的任何内容
注意:wait() 可能会虚假唤醒,建议使用 while 循环。
成功了!
public synchronized void buildWall() throws InterruptedException {
while (!hasFrame) {
wait();
}
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
添加"while()",但我已经不知道为什么了!
the other two thread havn't run! why?
正如@Peter 提到的那样,您已经发现,您需要 while(!boolean)
循环您的等待循环。出于几个原因,这是必要的。
正如 Peter 提到的那样,wait()
可能 return 因为虚假唤醒而不是正确的 notify()
调用。您需要确保您正在等待的条件实际上已经设置,然后循环并再次调用 wait()
如果没有。
但是,在您的情况下,与虚假唤醒无关,而与您的程序编写方式有关。因为您有一个 synchronized
对象(House
对象),所以当您调用 notifyAll()
时,所有团队线程都会被唤醒。当调用 buildFoundation()
方法时,它会将 hasFoundation
设置为 true 并唤醒所有团队。但只有框架团队才能真正开始工作——其他团队需要循环并等待一段时间,直到他们的布尔值设置为 true。
您可以更改代码以对每个步骤使用 不同的 锁,这将使代码更容易理解,尽管您仍然需要 while
循环。
最后,正如您已经发现的那样,您的 if ... else ...
模式没有任何意义,因为当团队等待时,当他们收到通知时,他们的构建方法只会 return 因为另一个东西在 else
.