繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM