Reputation: 6511
Suppose an elevator simulation program, visitors about to take a ride are to wait until any one of the elevator doors opens. i.e. 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?
Upvotes: 12
Views: 5757
Reputation: 1362
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).
Upvotes: 0
Reputation: 242686
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.
Upvotes: 1
Reputation: 15757
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()
.
Upvotes: 8
Reputation: 11401
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).
Upvotes: 1
Reputation: 53486
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)
Upvotes: 5