Мониторы и замки вопрос - PullRequest
0 голосов
/ 07 марта 2011

Если поток A обращается к методу потока B, который ожидает выполнения условия, будет ли поток A застрял в этом методе?Как я могу сделать так, чтобы поток A мог фактически проверять, ожидает ли поток B условие, и, следовательно, быть также приостановленным условием и сигнализироваться условием потока B, когда это будет сделано?

По сути, яМне интересно, как я могу запретить вложенным условиям удерживать родительский метод, вызывающий вложенный вызов (inter-threads).

Например:

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;
   }
}

В приведенном выше примере этослучится так, что каждый объект Person кормит другого, и, следовательно, застрянет в состоянии гонки.

Спасибо!

Ответы [ 2 ]

1 голос
/ 07 марта 2011

@ Ответ Мэтта МакГенри дает вам возможный подход к решению этой проблемы.

Однако вы должны быть осторожны, чтобы не просто заменить потенциальный тупик потенциальным livelock .

IMO, лучше разработать приложение так, чтобыбыть свободным от взаимоблокировок вместо того, чтобы уменьшать взаимоблокировки с помощью tryLock(...)

1 голос
/ 07 марта 2011

Посмотрите на метод tryLock() на java.util.concurrent.locks.Lock. Это позволяет вам попытаться получить блокировку, но возвращает (после необязательного тайм-аута) в случае сбоя, а не блокирует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...