简体   繁体   English

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

[英]How to use wait() and notifyAll() to run thread one by one?

I write a House class, it has four synchronized method. 我写了一个House类,它有四个同步方法。 I write four threads, and want they run one by one. 我编写了四个线程,并希望它们一个一运行。 but just first and second have run, the other havn't ? 但是只有第一和第二跑了,其他没有?

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();
    }
}

when run the main(),the result just: foundation ok frame ok 当运行main()时,结果只是:Foundation ok frame ok

the other two thread havn't run! 其他两个线程未运行! why? 为什么?

the ...Team class like this: ... Team类是这样的:

public class FoundationTeam implements Runnable {

    private House house;

    public FoundationTeam(House house) {
        this.house = house;
    }

    @Override
    public void run() {
        house.buildFoundation();
    }

}

this is just a demo, I want know how to use wait() and notifyAll(). 这只是一个演示,我想知道如何使用wait()和notifyAll()。

Please just solve this problem ok? 请解决这个问题好吗? Its' just a part of all what i want do. 这只是我想要做的所有事情的一部分。 Please just tell me why it's doesn't work, and how to solve? 请告诉我为什么它不起作用,以及如何解决?

when call wait(), this object won't be release? 当调用wait()时,该对象将不会被释放? and other threads can't call the other synchronized methods? 和其他线程不能调用其他同步方法?

If your method does wait(), it isn't going to run anything in the else block 如果您的方法确实使用了wait(),则它将不会在else块中运行任何else

Note: wait() can wake spuriously, a while loop is recommended. 注意:wait()可能会虚假唤醒,建议使用while循环。

the other two thread havn't run! 其他两个线程未运行! why? 为什么?

As @Peter mentioned and you've figured out, you need while(!boolean) loop around your wait loops. 正如@Peter提到的那样,您已经弄清楚了,您需要while(!boolean) wait循环周围使用while(!boolean)循环。 This is necessary for a couple of reasons. 这出于两个原因是必要的。

As Peter mentions, the wait() might return because of a spurious wakeup instead of a proper notify() call. 正如Peter所提到的, wait()可能由于虚假唤醒而不是正确的notify()调用而返回。 You need to make sure that the condition you are waiting for has actually been set and then loop and call wait() again if it hasn't. 您需要确保实际上正在设置您要等待的条件,然后循环并再次调用wait()如果尚未设置wait()

In your case however, it's less about spurious wakeups and more about how your program is written. 但是,就您而言,它与虚假唤醒无关,而与程序编写方式有关。 Because you have one synchronized object (the House object), when you call notifyAll() all of teams threads are awoken. 因为您有一个synchronized对象( House对象),所以当您调用notifyAll()所有团队线程都被唤醒。 When the buildFoundation() method is called, it sets hasFoundation to true and wakes up all of the teams. 调用buildFoundation()方法时,它将hasFoundation设置为true并唤醒所有团队。 But only the framing team can actually start work -- the other teams need to loop around and wait some more until their boolean has been set to true. 但是只有框架团队才能真正开始工作-其他团队需要循环并等待更多时间,直到布尔值设置为true。

You could change your code to use different locks for each of the steps which would make the code a bit easier to follow although you would still need the while loops. 您可以将代码更改为对每个步骤使用不同的锁,这将使代码易于使用,尽管您仍然需要while循环。

Lastly, as you've already figured out, your if ... else ... pattern makes no sense because when the teams are waiting, when they are notified, their build method will just return because the other stuff is in the else . 最后,正如您已经知道的那样, if ... else ...模式毫无意义,因为当团队等待时,当他们被通知时,他们的构建方法将返回,因为其他东西在else

It's work! 是工作!

public synchronized void buildWall() throws InterruptedException {
    while (!hasFrame) {
        wait();
    }
    hasWall = true;
    System.out.println("wall ok");
    notifyAll();
}

add the "while()", but i alredy don't know why! 添加“ while()”,但是我不知道为什么!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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