Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ReeantrantLock和条件变量_Java_Multithreading_Reentrantlock - Fatal编程技术网

Java ReeantrantLock和条件变量

Java ReeantrantLock和条件变量,java,multithreading,reentrantlock,Java,Multithreading,Reentrantlock,您好:)我正在学习Java中的重入锁和条件变量。我碰巧遇到这个。在本教程中,作者提供了一个利用ReentrantLock的生产者-消费者示例: public class CondDemo { public static void main(String[] args) { Shared s = new Shared(); new Producer(s).start(); new Consumer(s).start(); } } class

您好:)我正在学习Java中的重入锁和条件变量。我碰巧遇到这个。在本教程中,作者提供了一个利用ReentrantLock的生产者-消费者示例:

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');
   }
}
公共类演示
{
公共静态void main(字符串[]args)
{
共享s=新的共享();
新生产者。开始();
新消费者。开始();
}
}
类共享
{
私有易失性字符c;
可提供私有数据;
私人最终锁;
私人最终条件;
共享()
{
c='\u0000';
可用=错误;
锁=新的可重入锁();
condition=lock.newCondition();
}
Lock getLock()
{
返回锁;
}
char getSharedChar()
{
lock.lock();
尝试
{
而(!可用){
尝试
{
条件wait();
}
捕获(中断异常ie)
{
即printStackTrace();
}
}
可用=错误;
条件。信号();
}
最后
{
lock.unlock();
返回c;
}
}
无效设置共享字符(字符c)
{
lock.lock();
尝试
{
while(可用){
尝试
{
条件wait();
}
捕获(中断异常ie)
{
即printStackTrace();
}
}
这个.c=c;
可用=真实;
条件。信号();
}
最后
{
lock.unlock();
}
}
}
类生成器扩展线程
{
专用最终锁l;
私人最终共享的共享文件;
制作人(共享)
{
这个.s=s;
l=s.getLock();
}
@凌驾
公开募捐
{

对于(char ch='A';ch,这既不是必要的,也不是模式

我觉得这是一个丑陋的冗余锁,过去它的输出是干净的。我的意思是丑陋的,因为没有尝试最终确保一级解锁,它暴露了
共享
API的内部状态


为了更深入地学习Java并发,您可以使用或

Hmm获得相同的结果,这很奇怪。阅读这段代码,在我看来,锁定的锁可以再次被锁定-这不应该引发异常或什么吗?不,这是锁重入的基础。但是,当获得锁时,必须确保在正确的位置释放锁。但是获得多个锁有什么好处?它可以让您设计不必依赖代码路径的功能。例如,您可以有一个公共方法
foo()
,它执行关键代码(因此需要锁),然后它调用另一个公共方法
bar()
这两种方法也可以做关键的事情。因为这两种方法都是公共的,所以很难知道在哪种上下文中调用了
。如果您在事务管理方面有一些经验,则应用相同的逻辑。您不知道您的事务是绑定到您的方法还是绑定到更高的调用方。但必须在已打开的相同块级别上释放事务。这不提供问题的答案。批评aut或要求aut澄清hor,在他们的帖子下面留言。我已经说过这只是一个“夸夸其谈”锁所以既不是必需的,也不是模式。我已经明确添加了我的答案。关于如何使用ReentrantLock和条件变量,有更好的例子吗?你看了吗?你也可以看一看。我非常感激。我没有读过它们,但我是著名的,而且是
同步的任何应用程序t
/
notify
也适用。主要区别在于
API不是块绑定的(无论是最坏的还是最好的),通过使用多个
条件
实例,您可以拥有多组
等待
/
通知