ReentrantLock condition条件表达式理解

这个条件锁怎么进行理解呢。我觉得用生活中最常见的方式来理解会更好理解。reentrantlock的条件锁,生成一个条件,相当于生成了一把钥匙,每一把钥匙都可以开锁,也都可以加锁。如下

Condition aConditio = reentrantLock.newCondition();
Condition bConditio = reentrantLock.newCondition();
Condition cConditio = reentrantLock.newCondition();

相当于三把钥匙。而钥匙运行的逻辑是什么呢,就是一个条件能够正常运行需要满足的条件。我们将这样的一个模型放到生产者和消费者这里来看。

生产者:能够正常向“房间”中放东西的前提(条件)是什么——是这个房间是还有空间
消费者:能够正常从“房间”中取东西的前提(条件)是什么——是这个房间中有东西

我们的条件锁就出来了,就是如下haveSpaceConditionhaveDataCondition

那么对应的正常逻辑伪代码也就出来了

正常逻辑伪代码

public void put(data){
    // 先加锁
    reentrantlock.lock();
    
    // 内部处理逻辑
    doAddInner(data);
    // 当放完东西之后,记得通知下说现在有数据了
    haveDataCondition();
}

对应的消费者也是

public Object get(){
    // 先加锁
    reentranlock.lock();
    
    // 内部获取数据
    Object data = getFromInner();
    
    // 取出来之后,记得通知对方有空间了
    haveSpaceCondition();
}

在正常情况考虑完了之后,还需要考虑异常情况,就是在不能放数据的时候怎么办以及“房间”空了不能取怎么办,这种异常情况的处理

添加异常情况的逻辑伪代码

对生产者而言,异常情况是不能放东西了,就做异常处理(其实就是正常工作的条件锁阻塞)

public void put(data){
    // 先加锁
    reentrantlock.lock();
    
    if(isFull()){
        haveSpaceCondition.await();
    }
    
    // 内部处理逻辑
    doAddInner(data);
    // 当放完东西之后,记得通知下说现在有数据了
    haveDataCondition.notifyall();
}

对消费者而言,异常情况,就是不能取了,就做异常处理(其实就是正常工作的条件锁阻塞)

public Object get(){
     // 先加锁
    reentranlock.lock();
    
    if(isEmpty()){
        haveDataCondition.await();
    }
        
    // 内部获取数据
    Object data = getFromInner();
    
    // 取出来之后,记得通知对方有空间了
    haveSpaceCondition();
}

当学习完这样的锁之后再看生产者和消费者的Condition逻辑,是不是更好理解了,如下

生产者消费者代码

参考网上代码根据上面学习的方式再来看生产者消费者代码,是不是更好理解了

class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0) 
         notEmpty.await();
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   } 
 }

思维扩展

条件锁除了生产者消费者之外,更多能够使用到条件的地方,都可以采用上面的正常和异常处理逻辑的方式进行考虑,我们可以试试考虑,三个线程,两个不同的处理方式这种

a -> b -> c

这种处理看看,不知道是不是也是可以

源码参考:

https://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值