AbstractQueuedSynchronizer 学习

参考资料:

1、深入浅出AQS之独占锁模式
https://www.jianshu.com/p/71449a7d01af

2、深入浅出AQS之共享锁模式
https://www.jianshu.com/p/1161d33fc1d0


独占式

获取过程:

1、线程调用 acquire() 方法获取同步状态 state

2、如果 tryAcquire() 返回为 false (获取失败),将会调用 addWaiter(Node.EXCLUSIVE) 将当前获取同步状态失败的线程 作为新的节点 加入 同步队列(一个双向的 FIFO 队列,用于管理同步状态)的 tail,进行自旋(for(;;))(① 当前驱节点为 head,且获取到了同步状态,则设置当前节点为 head,原来 head 的 next 指向 null ② 如果获取失败后应该被 park,且 park 成功,则当前节点被阻塞,直到被 前驱节点 唤醒)

3、 如果 tryAcquire() 返回为 true,则获取同步状态成功

释放过程:

1、线程调用 release() 方法释放同步状态 state

2、如果 tryRelease() 方法返回 true,则调用 unparkSuccessor() 唤醒 head 的后继节点


共享式

获取:

1、线程调用 acquireShared() 方法获取同步状态 state

2、如果 tryAcquireShared() < 0,则获取同步状态失败。调用 addWaiter(Node.SHARED) 将当前获取同步状态失败的线程 作为新的节点 加入 同步队列(一个双向的 FIFO 队列,用于管理同步状态)的 tail,进行自旋(for(;;))(① 当前驱节点为 head,将尝试获取同步状态(tryAcquireShared()),如果获取到了同步状态(tryAcquireShared()>= 0),则设置当前节点为 head,并依次唤醒该节点后的所有共享节点,原来 head 的 next 指向 null ② 如果获取失败后应该被 park,且 park 成功,则当前节点被阻塞,直到被 前驱节点 唤醒)

3、如果 tryAcquireShared()>= 0,则获取同步状态失败。

释放:

1、线程调用 release() 方法释放同步状态 state

2、如果 tryRelease() 方法返回 true,则 doReleasedShared ()调用 unparkSuccessor() 唤醒 head 的后继节点


独占式与共享式的区别

跟 独占式 相比,共享式 的主要特征在于当一个在等待队列中的共享节点成功获取到 state 以后(它获取到的是共享锁),它必须要依次唤醒后面所有可以跟它一起共享当前锁资源的节点,毫无疑问,这些节点必须也是在等待共享锁


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值