ReentrantLock

ReentrantLock 概念

ReentrantLock 来自java.util.concurrent 包
除了Synchronized 外,ReentrantLock 同样可以实现同步机制。
Synchronized为API层面的互斥锁(lock0)和unlock()方法配合tryfinally语句块来完成)
ReentrantLock为原生语法层面的互斥锁。

ReentrantLock 是一个可重入的互斥锁, 拥有与 synchronized 相同的并发性和内存语义但是拥有更多的功能。
例如:等待可中断,可实现公平锁,以及锁可以绑定多个条件。

等待可中断

是指当持有锁的线程长期不释放锁的时候, 正在等待的线程可以选择放弃等
待, 改为处理其他事情, 可中断特性对处理执行时间非常长的同步块很有帮助。

公平锁

是指多个线程在等待同一个锁时, 必须按照申请锁的时间顺序来依次获得锁; 而
非公平锁则不保证这一点, 在锁被释放时, 任何一个等待锁的线程都有机会获得锁。
synchronized中的锁是非公平的, ReentrantLock默认情况下也是非公平的, 但可以通过带布尔
值的构造函数要求使用公平锁。

锁绑定多个条件

是指一个ReentrantLock对象可以同时绑定多个Condition对象, 而在
synchronized中, 锁对象的wait( ) 和notify( ) 或notifyAll( ) 方法可以实现一个隐含的条
件, 如果要和多于一个的条件关联的时候, 就不得不额外地添加一个锁, 而ReentrantLock则
无须这样做, 只需要多次调用newCondition( ) 方法即可。
如果需要使用上述功能, 选用ReentrantLock是一个很好的选择,
默认采用非公平锁。

ReentrantLock

底层基于抽象类 Sync 实现,它继承了 AQS,是公平锁、非公平锁的基础,子类实现了 lock()。 它模仿了 synchronized 的语义, 有一个与锁相关的获取计数器,如果拥有锁的某个线程再次得到锁,那么获取计数器就加1; 使用 AQS 的 state 来表示锁的持有数量。 如果获取锁成功,则将当前线程设置为锁的持有者;否则,将构建一个独占的 Node 加入同步队列中进行等待。
公平 Sync 是先到先得(相对于公平锁,多了一个判断:同步队列中是否已
经有其它线程的 Node); 非公平是直接尝试获取锁,如果获取失败才排队。
unlock(): state 减 1。 当 state 值减为 0 时,唤醒 head.next 线程, 然后尝试
获取锁,同时成功后设置该 Node 为 head。

非公平锁
lock():直接尝试通过 CAS 原子操作设置 state 从 0 变为 1,如果成功,则设
置当前线程为锁的持有者;否则继续调用 AQS 的 acquire(1)。
tryAcquire():如果 state=0,尝试设置 state 从 0 变为 1,如果成功,则设置
当前线程为锁的持有者;否则如果当前线程为锁的持有者, state 加 1。

公平锁
lock():直接调用 AQS 的 acquire(1)。
tryAcquire():如果 state=0,且同步队列中没有线程等待 ,尝试设置 state从 0变为 1,如果成功,则设置当前线程为锁的 持有者;否持有者, state加 1。

源码类方法

在这里插入图片描述

公平锁的实现是 底层获得当前线程,底层调用native 系统方法,并通过
public final Collection getQueuedThreads() {
ArrayList list = new ArrayList();
for (Node p = tail; p != null; p = p.prev) {
Thread t = p.thread;
if (t != null)
list.add(t);
}
return list;
}

通过线程集合 node 节点的方式存储等待的线程,以此来实现线程公平访问。但是会消耗更多系统性能。

ReentrantLock具有公平和非公平两种模式,也各有优缺点:
公平锁是严格的以FIFO的方式进行锁的竞争,但是非公平锁是无序的锁竞争,刚释放锁的线程很大程度上能比较快的获取到锁,队列中的线程只能等待,所以非公平锁可能会有“饥饿”的问题。但是重复的锁获取能减小线程之间的切换,而公平锁则是严格的线程切换,这样对操作系统的影响是比较大的,所以非公平锁的吞吐量是大于公平锁的,这也是为什么JDK将非公平锁作为默认的实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值