我写了一个House类,它有四个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()时,结果只是: 基础好的 框好了
另外两个线程已经运行了!为什么呢?
......像这样的团队课:
public class FoundationTeam implements Runnable {
private House house;
public FoundationTeam(House house) {
this.house = house;
}
@Override
public void run() {
house.buildFoundation();
}
}
这只是一个演示,我想知道如何使用wait()和notifyAll()。
请解决这个问题好吗?它'只是我想做的一部分。 请告诉我为什么它不起作用,以及如何解决?
当调用wait()时,这个对象不会被释放?和其他线程不能调用其他同步方法吗?
答案 0 :(得分:2)
如果您的方法执行wait(),则不会在LatLng center = new LatLng(40.384213, -3.875244);
List<LatLng> positions = new ArrayList<>();
positions.add(new LatLng(43.153102, 2.914307));
positions.add(new LatLng(42.976521, 1.508057));
positions.add(new LatLng(42.492353, 0.123779));
Display display = getActivity().getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
LatLngBounds bounds = findBounds(positions,center);
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds,width,height,10));
块中运行任何内容
注意:wait()可以虚假唤醒,建议使用while循环。
答案 1 :(得分:1)
另外两个线程已经运行了!为什么呢?
正如@Peter所提到的,你已经想通了,你需要while(!boolean)
循环你的等待循环。出于以下几个原因,这是必要的。
正如彼得所提到的,wait()
可能会因为虚假的唤醒而不是正确的notify()
召唤而返回。您需要确保实际上已经设置了您正在等待的条件,然后循环并再次呼叫wait()
,如果它没有。
然而,在你的情况下,它不是关于虚假的唤醒,而是更多关于程序的编写方式。因为您有一个synchronized
对象(House
对象),所以当您调用notifyAll()
时,所有团队线程都会被唤醒。调用buildFoundation()
方法时,它会将hasFoundation
设置为true并唤醒所有团队。但只有框架团队才能真正开始工作 - 其他团队需要循环并等待更多,直到他们的布尔值设置为true。
您可以更改代码,以便为每个步骤使用不同的锁定,这样可以使代码更容易理解,尽管您仍然需要while
循环。
最后,正如您已经发现的那样,您的if ... else ...
模式毫无意义,因为当团队等待时,当他们收到通知时,他们的构建方法将会返回,因为其他内容在else
。
答案 2 :(得分:0)
这是工作!
public synchronized void buildWall() throws InterruptedException {
while (!hasFrame) {
wait();
}
hasWall = true;
System.out.println("wall ok");
notifyAll();
}
添加“while()”,但我不知道为什么!