简体   繁体   中英

In java, how to wait on multiple `Conditions` until any one of them is signaled

Suppose an elevator simulation program, visitors about to take a ride are to wait until any one of the elevator doors opens. ie I want to wait on multiple Conditions until any one of them is signaled.

Actually, it doesn't have to be Conditions , other approaches that can fulfill my need is welcome.

How can this be done in Java?

You might find CountDownLatch does the job you need. You would instantiate the latch with a count of 1:

CountDownLatch latch = new CountDownLatch(1);

and then share it between your threads. All the threads that wait for the doors to open will do latch.await() . This method will not return until another thread calls latch.countDown() .

You might want to check out Observer and Observable . You will still have to handle treading issues but with Observer you at least have an easy way for the simulator to know when a door opens (triggers an event)

Rather than a set of conditions, I'd use a BlockingQueue<Door> , ( Door is an enum of the doors in the lift) where threads which want to use a door call take() on the queue, and threads which are opening a door call put(Door.ONE) . and then uses drainTo to remove any other open doors (presumably there's another mechanism to tell the door opening threads that the lift has left and that they can't open any more doors).

Generally speaking, Lock protects shared state and Condition is used to wait for particular condition on that state.

But in your task you actually have two sets of orthogonal states - states of elevators and states of floors. It means that if you want to use Lock / Condition primitives to work with this task, you need to create separate locks and conditions for these states.

That is, when elevator arrives at the floor, it acquires its own lock and a lock of the floor, and then signals a condition associated with the floor, so that visitors waiting on the floor are awakened. Also pay attention on lock ordering to avoid deadlocks in this scheme.

Condition is an unfortunate name, IMO. Another way to think of java.util.concurrent.locks.Condition is as a signal . So another way to think of your problem is that you have 1 "condition": a door is opened. And whenever any of your elevator doors opens, you signal the generic "door is opened" condition. Once the waiting thread is awake it will need to find which one is open (or find and select one if multiple are open).

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