nubela
nubela

Reputation: 17294

Monitors and Locks question

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

Answers (2)

Stephen C
Stephen C

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

Matt McHenry
Matt McHenry

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

Related Questions