Reputation: 17294
If thread A accesses thread B's method, which happens to be awaiting a condition, will thread A be stuck in that method? How can I make it such that thread A could actually check if thread B is awaiting a condition, and hence be suspended by a condition as well and be signaled by thread B's condition when it is done?
Basically, I'm wondering how I can prevent nested conditions from holding up a parent method calling the nested call (inter-threads).
For example:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Person {
final Lock lock = new ReentrantLock();
Condition isFree = lock.newCondition();
State state;
public void eat() throws InterruptedException {
lock.lock();
try {
while (state != State.WAITING) {
isFree.await();
}
//begin eating
state = State.EATING;
Thread.sleep(1000);
state = State.WAITING;
isFree.signal();
} finally {
lock.unlock();
}
}
public void feed(Person person) throws InterruptedException {
lock.lock();
try {
while (state != State.WAITING) {
isFree.await();
}
//begin intention to feed
person.eat();
} finally {
lock.unlock();
}
}
enum State {
EATING, WAITING;
}
}
In the above example, it could be happen that every Person object is feeding another, and hence be stuck in a race condition.
Thanks!
Upvotes: 0
Views: 134
Reputation: 719346
@Matt McHenry's answer gives you a possible approach to solving this problem.
However, you need to be careful that you don't just replace a potential deadlock with a potential livelock.
IMO, it is better to design your application to be deadlock free rather than to mitigate the deadlocks using tryLock(...)
Upvotes: 1
Reputation: 20929
Have a look at the tryLock()
method on java.util.concurrent.locks.Lock
. This lets you attempt to acquire a lock, but returns (after an optional timeout) if it fails, rather than blocking.
Upvotes: 1