Sync

   abstract static class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = -5179523762034025860L;abstract void lock();/***非公平锁Acquire*/final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//竞争锁if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//如果本线程已经获得锁,仅增加state。else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;}//当前独占线程是否是本线程(重入锁可重入的判断)protected final boolean isHeldExclusively() {return getExclusiveOwnerThread() == Thread.currentThread();}final ConditionObject newCondition() {return new ConditionObject();}final Thread getOwner() {return getState() == 0 ? null : getExclusiveOwnerThread();}final int getHoldCount() {return isHeldExclusively() ? getState() : 0;}final boolean isLocked() {return getState() != 0;}/*** Reconstitutes the instance from a stream (that is, deserializes it).*/private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {s.defaultReadObject();setState(0); // reset to unlocked state}}

NonfairSync

    static final class NonfairSync extends Sync {private static final long serialVersionUID = 7316153563782823691L;final void lock() {//首先尝试一下,不成功再acquireif (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}}

FairSync

  static final class FairSync extends Sync {private static final long serialVersionUID = -3000897897090466540L;final void lock() {acquire(1);}protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//判断本线程在队列中是否有前置节点(即有优先本节点的)if (!hasQueuedPredecessors() &&     //没有则尝试获取锁。compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//如果本线程已获得锁,则重入else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}}
    public final boolean hasQueuedPredecessors() {// The correctness of this depends on head being initialized// before tail and on head.next being accurate if the current// thread is first in queue.Node t = tail; // Read fields in reverse initialization orderNode h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());}

ReentrantLock

    public void lock() {//根据公平锁标志决定call哪个sync.locksync.lock();}public void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}public boolean tryLock() {//call非公平方式return sync.nonfairTryAcquire(1);}public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}public void unlock() {sync.release(1);}
    protected final boolean tryRelease(int releases) {//减releasesint c = getState() - releases;//如果当前线程不是独占线程,则抛出异常if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {//仅当c为0时,才表示一个线程完全释放了锁,因为可重入。free = true;setExclusiveOwnerThread(null);}setState(c);return free;}

AbstractQueuedSynchronizer参考:AbstractQueuedSynchronizer源码解析

ConditionObject参考:ConditionObject源码

公平锁相比非公平锁的不同

公平锁模式下,对锁的获取有严格的条件限制。在同步队列有线程等待的情况下,所有线程在获取锁前必须先加入同步队列。队列中的线程按加入队列的先后次序获得锁。

为什么非公平锁性能好

非公平锁对锁的竞争是抢占式的(队列中线程除外),线程在进入等待队列前可以进行两次尝试,这大大增加了获取锁的机会。这种好处体现在两个方面:
1.线程不必加入等待队列就可以获得锁,不仅免去了构造结点并加入队列的繁琐操作,同时也节省了线程阻塞唤醒的开销,线程阻塞和唤醒涉及到线程上下文的切换和操作系统的系统调用,是非常耗时的。在高并发情况下,如果线程持有锁的时间非常短,短到线程入队阻塞的过程超过线程持有并释放锁的时间开销,那么这种抢占式特性对并发性能的提升会更加明显。
2.减少CAS竞争。如果线程必须要加入阻塞队列才能获取锁,那入队时CAS竞争将变得异常激烈,CAS操作虽然不会导致失败线程挂起,但不断失败重试导致的对CPU的浪费也不能忽视。除此之外,加锁流程中至少有两处通过将某些特殊情况提前来减少CAS操作的竞争,增加并发情况下的性能。一处就是获取锁时将非重入的情况提前,如下图所示

ReentrantLock源码相关推荐

  1. JUC AQS ReentrantLock源码分析

    Java的内置锁一直都是备受争议的,在JDK 1.6之前,synchronized这个重量级锁其性能一直都是较为低下,虽然在1.6后,进行大量的锁优化策略,但是与Lock相比synchronized还 ...

  2. 多线程(三)之ReentrantLock源码解析

    2019独角兽企业重金招聘Python工程师标准>>> 今天分析ReentrantLock类的源码,在看源码之前,先学习AQS(AbstractQueuedSynchronizer) ...

  3. Java8 ReentrantLock 源码分析

    一.ReentrantLock 概述 1.1 ReentrantLock 简介 故名思义,ReentrantLock 意为可重入锁,那么什么是可重入锁呢?可重入意为一个持有锁的线程可以对资源重复加锁而 ...

  4. Java并发编程-ReentrantLock源码分析

    一.前言 在分析了 AbstractQueuedSynchronier 源码后,接着分析ReentrantLock源码,其实在 AbstractQueuedSynchronizer 的分析中,已经提到 ...

  5. synchronized 和 reentrantlock 区别是什么_JUC源码系列之ReentrantLock源码解析

    目录 ReentrantLock 简介 ReentrantLock 使用示例 ReentrantLock 与 synchronized 的区别 ReentrantLock 实现原理 Reentrant ...

  6. 面试官系统精讲Java源码及大厂真题 - 32 ReentrantLock 源码解析

    32 ReentrantLock 源码解析 才能一旦让懒惰支配,它就一无可为. 引导语 上两小节我们学习了 AQS,本章我们就要来学习一下第一个 AQS 的实现类:ReentrantLock,看看其底 ...

  7. 【java】java ReentrantLock 源码详解

    文章目录 1.概述 2.问题 3.ReentrantLock源码分析 3.1 类的继承关系 3.2 类的内部类 3.2.1 Sync类 3.2.2 NonfairSync类 3.2.3 FairSyn ...

  8. ReentrantLock源码分析

    ReentrantLock源码分析 前言 最近公司比较忙,整天忙着做项目.做需求,感觉整个人昏昏沉沉的,抬头看天空感觉都是灰色的~~,其实是杭州的天本来就是这个颜色,手动滑稽`~(^o^)/~`.废话 ...

  9. 闲聊AQS面试和源码解读---可重入锁、LockSupport、CAS;从ReentrantLock源码来看公平锁与非公平锁、AQS到底是怎么用CLH队列来排队的?

    AQS原理可谓是JUC面试中的重灾区之一,今天我们就来一起看看AQS到底是什么? 这里我先整理了一些JUC面试最常问的问题? 1.Synchronized 相关问题以及可重入锁 ReentrantLo ...

  10. 【并发编程】 --- Reentrantlock源码解析5:再探不可中断性 + 线程unpark后诡异的Thread.interrupted()判断

    文章目录 1 想要读懂这篇文章必须要拥有的前置知识 2 想写这篇文章的原因 3 困扰我很久的Reentrantlock源代码1 --- 貌似无用的变量failed 4 困扰我很久的Reentrantl ...

最新文章

  1. Go 学习笔记(35)— Go 接口 interface (接口声明、接口初始化、接口方法调用、接口运算、类型断言、类型查询、空接口)
  2. Xcode的一些控制台命令
  3. ZYNQ 调试遇到的问题
  4. linux 线程_浅谈Linux线程模型
  5. kubernetes1.8.4安装指南 -- 5. 证书生成
  6. Java多线程(九)之ReentrantLock与Condition
  7. JQueryEasyUI学习笔记(一)
  8. 3.4 tensorflow2实现两总体样本尺度参数的秩检验法——python实战
  9. mysql面试必会6题经典_经典sql面试题及答案第7期
  10. ARCore1.2使用入门(一) ------ 将ARCore案例打包成Android/iOS运行测试(unity开发)
  11. VBS病毒(爱虫病毒) 源代码
  12. spring cloud day(6) gateway网关
  13. 解读制造业数字化转型的六大因素
  14. 老版本的linux内核中mtd test 出现 mtd_oobtest: error: verify failed at 0xXXXX 问题
  15. iOS12 Xcode10正式版问题汇总以及新特性(持续更新中....)
  16. python复数计算符号_Python:基本运算、基本函数(包括复数)、Math模块、NumPy模块...
  17. “拓维元”震撼发布,拓维信息软硬全栈国产自研战略再落一子!
  18. 耀世升级发布,阿里新出第三版Java多线程核心技术手册PDF全彩版
  19. 如何直接打印int[]数组
  20. 第七章 将文件内容复制到另外文件

热门文章

  1. 如何提高Google Adsense单价:点击率篇
  2. java类初始化顺序
  3. 【Spring学习】RestTemplate访问Rest服务总结
  4. idea 开发spark 程序代码
  5. 【css3】旋转倒计时
  6. 产品经理十八章:产品创新能力(二)
  7. eclipse更新time out的问题
  8. MySQL主从复制原理应用基础
  9. 与其他Javascript类库冲突解决方案
  10. 数据库 三范式最简单最易记的解释