admin管理员组文章数量:1599543
这里不讲代码,只是用图大概描述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
对象的双向队列中分别对应firstWaiter
、lastWaiter
,加入完成之后,释放独占锁,并阻塞自身等待其他持独占锁的线程调用signal
释放。
T3成了锁的持有者,上面俩哥都等着斥锁人来通知他们。
当持锁的线程调用signal方法时,队列会发生变化
condition.signal();
这里要注意的是:调用signal方法并不会唤醒condition中的线程。
比如这里的场景:
- T3 调用了signal方法,会先从condition队列中找到等待时间最长的,【先进先出嘛,第一个进去的肯定是排队最长的。】
- 拿到T1线程之后,将T1线程加入到AQS队列中排着。
其实这里就是做了线程从队列中的迁移,不会被立即唤醒,毕竟T3还没释放呢!T1从一开始持有锁的时候,也是自己先释放才能唤醒下一个线程。
这时候持R锁的T3释放锁了
当T3释放锁的时候,按照之前流程串起来。
排在等待队列的T1被唤醒,成为持锁人。
当然会存在一些竞争情况,比如这时候排队的可能不是T1,又或者T3释放锁的一瞬间,T456又来竞争锁。
如果T1没有抢到,则乖乖在等待队里里面待着。
不会影响流程。
总结
- 同一时刻只有一个对象获取独占锁,持有了这个锁的人才能调用await和sign方法。
- await方法会释放独占锁,并且将自身加入到condition队列中。
- signal方法不会立即唤醒await中的线程,而是将Condition队列中的线程转移到AQS队列中。
- 当持锁线程释放锁时,AQS队列的线程再抢到则会被唤醒。
以上言论仅个人理解,欢迎交流,共同探讨!
本文标签: 方法场景简单conditionReentrantLock
版权声明:本文标题:ReentrantLock中Condition的wait方法、signal方法简单场景回顾 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1728324396a1154244.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论