浅析同步队列器AbstractQueuedSynchronizer和ReentrantLock

AbstractQueuedSynchronizer

队列同步器AbstractQueuedSynchronizer是整个JUC锁框架的基石,通过同步状态量state、CAS、ConditionObject等组件和一系列操作实现线程间的状态同步,也是CountDownLatch、Semaphore等并发工具的实现基础。
队列同步器包含下列核心组件:
1.同步变量state:volatile修饰,CAS操作更新,两者保证状态一致性;
2.内部类Node:代表竞争同步资源的线程节点,包含指向前后节点的引用,当存在多线程竞争时形成一个包含首尾索引的双向链表,也是队列同步器名称的由来。Node类包含节点类型(独占/共享)、等待状态(waitStatus,理解有难度,单独总结)、指向所代码线程的索引等核心要素;
3.内部类ConditionObject:Condition接口具体实现,通过await()/signal()实现线程间通信,Conditon实例通过首尾索引维护一个等待队列;
4.exclusiveOwnerThread为什么不需要volatile修饰:只有获得锁的线程才能修改exclusiveOwnerThread,获取成功时改成当前线程,释放时置为null。基于这个前提,获得锁的线程始终能正确的知道exclusiveOwnerThread是不是自身,而对于未获得锁的线程,它看到的exclusiveOwnerThread始终是null或者其他线程,不会是自身,所以是线程安全的。

其他细节:
1.同步队列的头结点为占有所的线程节点,或者为空;
2.节点的阻塞和唤醒通过LockSupport.park和LockSupport.unpark实现,每次唤醒头结点的下一个节点,并将其设置为头结点;
3.队列同步器维护一个同步队列和多个等待队列:Condition.signal操作的实质是将等待队列的头结点出队,并设置为同步队列的尾结点,Condition.signalAll操作的实质是将等待队列的所有结点出队,追加到同步队列的尾部。

ReentrantLock

特点:
1.可重入:线程已经占有锁的情况下可以重复的抢占同一个锁,每次的重入即是state的累加;
2.公平和非公平:可重入锁有两个队列同步器的内部实现类,公平同步锁FairSync和非公平同步锁NonfairSync,区别在于新线程来竞争锁时,公平锁会将线程节点放在等待队列尾部,非公平锁会尝试抢占锁,抢占失败再加入队列尾部。
3.关于中断:lockInterruptibly()可以响应中断,终止阻塞,抛出InterruptedException;如果使用常规的lock(),尝试中断线程,会中止阻塞,引发自旋,重新阻塞。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值