2015-10-20 4 views
3

Здравствуйте, я узнаю о блокировке повторного входа и переменной условия в Java. Мне довелось встретить это tutorial. В учебнике, автор предоставляет производитель-потребитель пример использующего ReentrantLock:ReeantrantLock и переменная условия

public class CondDemo 
{ 
    public static void main(String[] args) 
    { 
     Shared s = new Shared(); 
     new Producer(s).start(); 
     new Consumer(s).start(); 
    } 
} 

class Shared 
{ 
    private volatile char c; 
    private volatile boolean available; 
    private final Lock lock; 
    private final Condition condition; 

    Shared() 
    { 
     c = '\u0000'; 
     available = false; 
     lock = new ReentrantLock(); 
     condition = lock.newCondition(); 
    } 

    Lock getLock() 
    { 
     return lock; 
    } 

    char getSharedChar() 
    { 
     lock.lock(); 
     try 
     { 
     while (!available) { 
      try 
      { 
       condition.await(); 
      } 
      catch (InterruptedException ie) 
      { 
       ie.printStackTrace(); 
      } 
     } 
     available = false; 
     condition.signal(); 
     } 
     finally 
     { 
     lock.unlock(); 
     return c; 
     } 
    } 

    void setSharedChar(char c) 
    { 
     lock.lock(); 
     try 
     { 
     while (available) { 
      try 
      { 
       condition.await(); 
      } 
      catch (InterruptedException ie) 
      { 
       ie.printStackTrace(); 
      } 
     } 
     this.c = c; 
     available = true; 
     condition.signal(); 
     } 
     finally 
     { 
     lock.unlock(); 
     } 
    } 
} 

class Producer extends Thread 
{ 
    private final Lock l; 

    private final Shared s; 

    Producer(Shared s) 
    { 
     this.s = s; 
     l = s.getLock(); 
    } 

    @Override 
    public void run() 
    { 
     for (char ch = 'A'; ch <= 'Z'; ch++) 
     { 
     l.lock(); 
     s.setSharedChar(ch); 
     System.out.println(ch + " produced by producer."); 
     l.unlock(); 
     } 
    } 
} 

class Consumer extends Thread 
{ 
    private final Lock l; 

    private final Shared s; 

    Consumer(Shared s) 
    { 
     this.s = s; 
     l = s.getLock(); 
    } 

    @Override 
    public void run() 
    { 
     char ch; 
     do 
     { 
     l.lock(); 
     ch = s.getSharedChar(); 
     System.out.println(ch + " consumed by consumer."); 
     l.unlock(); 
     } 
     while (ch != 'Z'); 
    } 
} 

являются методами l.lock() и l.unlock() в Producer и Consumer ненужных? Я замечаю, что мы уже применили блокировку/разблокировку в методах объекта getSharedChar() и setSharedChar(). Или это предложенная модель использования переменных условия?

Это не очень хорошая практика, можете ли вы предоставить ссылку для лучшего примера?

Спасибо :)

+0

Хм, странно. Читая этот код, мне кажется, что заблокированная блокировка может быть заблокирована снова - разве это не должно исключать исключение или что-то еще? – Manu

+1

Нет, это основная функция блокировки входа. Однако при получении блокировки есть [счет получения] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html#getHoldCount--), чтобы обеспечить блокировку освобождение осуществляется в нужном месте. – LoganMzz

+0

Но в чем преимущество получения нескольких замков? – hackjutsu

ответ

2

Это не необходимо, ни шаблон.

IMHO Это уродливая резервная блокировка, используемая для чистого вывода. Я имею в виду уродство, потому что нет попытки - наконец, обеспечить разблокировку первого уровня, и он раскрывает внутреннее состояние API Shared.

Чтобы углубиться в изучении Java параллелизм, вы можете получить тот же результат с помощью SynchronousQueue или Exchanger

+2

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. – marian0

+0

Я уже говорил, что это всего лишь «кустарный» замок, поэтому ни необходимый, ни шаблон. Я явно добавляю свой ответ. – LoganMzz

+0

Есть ли лучший пример того, как использовать переменную ReentrantLock и Condition? – hackjutsu

 Смежные вопросы

  • Нет связанных вопросов^_^