ReeantrantLock和Condition变量

时间:2015-10-20 06:55:45

标签: java multithreading reentrantlock

您好:)我在Java中了解了重入锁定和条件变量。我碰巧碰到了这个tutorial。在本教程中,作者使用ReentrantLock提供了一个Producer-Consumer示例:

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()中的方法ProducerConsumer是否不必要?我注意到我们已经在Shared对象的getSharedChar()setSharedChar()方法中应用了锁定/解锁。或者这是使用条件变量的建议模式?

这是一个不好的做法,你能提供一个更好的例子的链接吗?

感谢:)

1 个答案:

答案 0 :(得分:2)

这既不是必需的,也不是一种模式。

恕我直言这是一个丑陋的冗余锁,用于清洁输出。我的意思是丑陋,因为没有尝试 - 最终确保第一级解锁并且它暴露了Shared API的内部状态。

要深入学习Java并发,您可以使用SynchronousQueueExchanger

获得相同的结果