简体   繁体   中英

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

I write a House class, it has four synchronized method. 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

the other two thread havn't run! why?

the ...Team class like this:

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().

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? 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

Note: wait() can wake spuriously, a while loop is recommended.

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. 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. 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.

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. When the buildFoundation() method is called, it sets hasFoundation to true and wakes up all of the teams. 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.

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.

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 .

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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