如何使用wait()和notifyAll()逐个运行线程?

时间:2016-09-29 12:31:42

标签: java multithreading java-threads

我写了一个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()时,这个对象不会被释放?和其他线程不能调用其他同步方法吗?

3 个答案:

答案 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()”,但我不知道为什么!