博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
死磕源码系列(ReentrantLock)
阅读量:7041 次
发布时间:2019-06-28

本文共 2036 字,大约阅读时间需要 6 分钟。

hot3.png

前言

  • 在高并发领域,ReentrantLock有着广泛的用处,防止多线程带来的并发问题
  • 对于源码,很多人和我一开始一样都觉得非常神秘
  • 这次我将对ReentrantLock进行全方面的揭秘

核心

  • AbstractQueuedSynchronizer
    • AQS是JDK实现的CAS同步器。里面的核心是state和两个node
    • state标识同步器现在的状态,node作为队列串联同步器中的节点
    • 使用volatile保证参数的可见性
volatile Node prev;volatile Node next;private volatile int state;

整体结构

  • ReentrantLock 调用内部类Sync,Sync继承AbstractQueuedSynchronizer

整体流程

  • ReentrantLock调用内部类Sync的acquire方法,底层走的是AbstractQueuedSynchronizer,AbstractQueuedSynchronizer会尝试获取锁,获取失败之后会加入队列中,然后节点自旋去获取锁,一旦成功就将自己的节点至于头部,然后退出。
  • cas实现(compareAndSet)。jdk9之前使用的是unsafe,jsk9之后使用的是varHandler。

核心代码

AQS:

public final void acquire(int arg) {        if (!tryAcquire(arg) &&            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))            selfInterrupt();    }
  • tryAcquire是第一次尝试获取所,公平锁和非公平锁的区别只是判断自己节点是否除了head节点外还是在自己前面的,校验的是公平锁,不校验的是非公平锁
  • addWaiter是节点加入到队列中
  • acquireQueued里面执行的就是自旋操作
final boolean acquireQueued(final Node node, int arg) {        boolean failed = true;        try {            boolean interrupted = false;            //自旋开始            for (;;) {                final Node p = node.predecessor();                //尝试开始获取锁                if (p == head && tryAcquire(arg)) {                    setHead(node);                    p.next = null; // help GC                    failed = false;                    return interrupted;                }                if (shouldParkAfterFailedAcquire(p, node) &&                    parkAndCheckInterrupt())                    interrupted = true;            }        } finally {            if (failed)                cancelAcquire(node);        }    }

释放锁

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;        }

转载于:https://my.oschina.net/u/3159571/blog/3003157

你可能感兴趣的文章
PHP 获取当地准确时间
查看>>
【装机知识】电源知识整理
查看>>
Python学习笔记
查看>>
OFFICE--三线表的制作
查看>>
php smarty模版引擎中的缓存应用
查看>>
ImportError: numpy.core.multiarray failed to import
查看>>
代码,显示IPhone剩余磁盘空间
查看>>
wf跟webx开源我见
查看>>
如何使用 log4net 以日期为文件名输出(转载)
查看>>
delphi演示程序
查看>>
iOS进阶:Objective-C runtime(一)
查看>>
Hash
查看>>
Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web mod
查看>>
实现点击a标签页面跳转后颜色高亮
查看>>
关于php中checkbox的操作特殊点
查看>>
当用户切换了窗口后改变title,感觉挺有趣的,收藏了
查看>>
【Erlang新手成长日记】HTTP客户端
查看>>
AndroidStudio SVN检出
查看>>
[AC自动机][HDU3065]
查看>>
PCIe link up bug 分析
查看>>