ReentrantLock中Condition的wait方法、signal方法简单场景回顾

这里不讲代码,只是用图大概描述Condition在ReentrantLock中做了一件怎么样的事情。

流程描述

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();

当多个线程开始抢占ReentrantLock的锁时

lock.lock();

独占锁的获取
ReentrantLock锁时互斥的,同一时刻只可能有一个线程获取到使用权,其他没有抢到的则乖乖进入等待队列,等待被唤醒。

当抢到独占锁的线程调用Condition的await方法时,线程开始阻塞

condition.await();

这里为了condition队列好理解,就假设T1、T2先后调用了await方法,释放了独占锁。

在这里插入图片描述
此时T1、T2先后调用了await·的方法的线程会被加入到ConditionObject对象的双向队列中分别对应firstWaiterlastWaiter,加入完成之后,释放独占锁,并阻塞自身等待其他持独占锁的线程调用signal释放

T3成了锁的持有者,上面俩哥都等着斥锁人来通知他们。

当持锁的线程调用signal方法时,队列会发生变化

condition.signal(); 

在这里插入图片描述
这里要注意的是:调用signal方法并不会唤醒condition中的线程
比如这里的场景:

  1. T3 调用了signal方法,会先从condition队列中找到等待时间最长的,【先进先出嘛,第一个进去的肯定是排队最长的。】
  2. 拿到T1线程之后,将T1线程加入到AQS队列中排着。

其实这里就是做了线程从队列中的迁移,不会被立即唤醒,毕竟T3还没释放呢!T1从一开始持有锁的时候,也是自己先释放才能唤醒下一个线程。

这时候持R锁的T3释放锁了

T3要释放锁了

当T3释放锁的时候,按照之前流程串起来。
排在等待队列的T1被唤醒,成为持锁人。

当然会存在一些竞争情况,比如这时候排队的可能不是T1,又或者T3释放锁的一瞬间,T456又来竞争锁。
如果T1没有抢到,则乖乖在等待队里里面待着。

不会影响流程。

总结

  1. 同一时刻只有一个对象获取独占锁,持有了这个锁的人才能调用await和sign方法。
  2. await方法会释放独占锁,并且将自身加入到condition队列中。
  3. signal方法不会立即唤醒await中的线程,而是将Condition队列中的线程转移到AQS队列中。
  4. 当持锁线程释放锁时,AQS队列的线程再抢到则会被唤醒。

以上言论仅个人理解,欢迎交流,共同探讨!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaCondition类是Java多线程编程的一个重要概念,它提供了类似于Object类的wait()、notify()和notifyAll()方法的功能,并且更加灵活和强大。Condition.await()方法Condition的一个实例方法,用于线程等待某个条件的发生。 当线程调用Condition.await()方法时,它释放它所持有的,并且进入等待状态,直到其他线程调用相同的Condition对象上的signal()方法signalAll()方法来唤醒它。与Object.wait()方法不同的是,Condition.await()方法可以选择性地等待某个特定条件的发生,而不是简单地等待任意条件的发生。 Condition.await()方法的使用需要与配合使用,通常的做法是在获取之后调用Condition.await()方法,然后在条件满足时调用Condition.signal()或Condition.signalAll()方法来唤醒等待的线程。具体流程如下: 1. 获取。 2. 如果条件不满足,调用Condition.await()方法,线程进入等待状态。 3. 如果条件满足,执行相应的操作。 4. 调用Condition.signal()或Condition.signalAll()方法,唤醒等待的线程。 5. 释放。 需要注意的是,Condition.await()方法可能出现虚假唤醒的情况,因此在使用时应该总是在循环调用Condition.await()方法,并在循环检查条件是否满足。例如: ``` final Lock lock = new ReentrantLock(); final Condition condition = lock.newCondition(); // 线程1 lock.lock(); try { while (!conditionSatisfied) { condition.await(); } // 执行相应的操作 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } // 线程2 lock.lock(); try { conditionSatisfied = true; condition.signal(); } finally { lock.unlock(); } ``` 在这个例子,线程1在获取之后调用Condition.await()方法等待条件满足,线程2在获取之后改变条件状态并调用Condition.signal()方法唤醒等待的线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值