ReeantrantLock 和条件变量

ReeantrantLock and Condition variable

你好:)我正在学习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');
   }
}

ProducerConsumer中的方法l.lock()l.unlock()是不需要的吗?我注意到我们已经在 Shared 对象的 getSharedChar()setSharedChar() 方法中应用了 lock/unlock。或者这是使用条件变量的建议模式?

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

谢谢:)

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

恕我直言,这是一个丑陋的冗余锁,曾经有干净的输出。我的意思是丑陋,因为没有 try-finally 来确保第一级解锁,它暴露了 Shared API.

的内部状态

要更深入地学习 Java 并发,您可以使用 SynchronousQueue or Exchanger

获得相同的结果