Lock底层原理

LOCK 的实现类其实都是构建在 AbstractQueuedSynchronizer 上,为何图中没有用 UML 线表示呢,这是每个 Lock 实现类都持有自己内部类 Sync 的实例,而这个 Sync 就是继承 AbstractQueuedSynchronizer (AQS)。为何要实现不同的 Sync 呢?这和每种 Lock 用途相关。另外还有 AQS 的 State 机制。

FairSync 与 NonfairSync 的区别在于,是不是保证获取锁的公平性,因为默认是 NonfairSync(非公平性)

AQS

可以看到Lock锁的底层实现是AQS

1.定义

AQS(AbstractQuenedSynchronizer ),抽象的队列式同步器,除了 java 自带的 synchronized 关键字之外的锁机制。

2.AQS 的核心思想

如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁(CLH 锁是一个自旋锁。能确保无饥饿性。提供先来先服务的公平性)实现的,即将暂时获取不到锁的线程加入到队列中。

AQS 是将每一条请求共享资源的线程封装成一个 CLH 锁队列的一个结点(Node),来实现锁的分配。

3.实现

AQS 基于 CLH 队列,用 volatile 修饰共享变量 state,线程通过 CAS 去改变状态符,成功则获取锁成功,失败则进入等待队列,等待被唤醒。

4.总结

  • lock 的存储结构:一个 int 类型状态值(用于锁的状态变更),一个双向链表(用于存储等待中的线程)
  • lock 获取锁的过程:本质上是通过 CAS 来获取状态值修改,如果当场没获取到,会将该线程放在线程等待链表中。
  • lock 释放锁的过程:修改状态值,调整等待链表。

可以看到在整个实现过程中,lock 大量使用 CAS + 自旋。因此根据 CAS 特性,lock 建议使用在低锁冲突的情况下。目前 java1.6 以后,官方对 synchronized 做了大量的锁优化(偏向锁、自旋、轻量级锁)。因此在非必要的情况下,建议使用 synchronized 做同步操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值