当前位置: 首页 > wzjs >正文

在线收录郑州网站运营专业乐云seo

在线收录,郑州网站运营专业乐云seo,彩页设计素材,网站建设费用的会计分录ReentrantLock源码解析 概括AQS实现构造方法lock方法公平锁执行lock方法公平锁lock流程图 非公平锁执行lock方法线程获取公平锁和非公平锁的区别 释放锁 概括 ReentrantLock,是Lock接口的实现类,我们查看其内的一些方法 我们可以发现其内大部分方法都是…

ReentrantLock源码解析

  • 概括
    • AQS实现
    • 构造方法
    • lock方法
      • 公平锁执行lock方法
        • 公平锁lock流程图
      • 非公平锁执行lock方法
        • 线程获取公平锁和非公平锁的区别
    • 释放锁


概括

ReentrantLock,是Lock接口的实现类,我们查看其内的一些方法

在这里插入图片描述
在这里插入图片描述
我们可以发现其内大部分方法都是通过sync对象来实现的,查看sync:
在这里插入图片描述
如上图,sync是一个抽象类,继承了AQS,而AQS的主要实现则是通过一个共享变量以及先进先出的队列实现,如下:

AQS实现

在这里插入图片描述
由volatile修饰的state,表示共享资源的状态,当其为0时表示资源空闲,>0时表示资源被锁定
在这里插入图片描述
而若有线程想要获取锁,就调用以上方法尝试使用CAS修改state变量,修改成功则表示成功获取锁,如果获取锁失败,线程就会被包装成结点加入先进先出的队列中,在AQS中该队列是通过双向链表实现的,如以下方法:
在这里插入图片描述

构造方法

我们已经知道大概知道了AQS的基本实现原理,而sync又继承了AQS。
查看其构造方法:

 public ReentrantLock() {sync = new NonfairSync();}public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}

其包括两个构造方法,第一个构造方法不传入参数值,默认创建非公平锁,而第二个构造方法会根据传入的参数决定创建非公平锁还是公平锁,我们来看看什么是公平锁和非公平锁。
在这里插入图片描述
在这里插入图片描述
可以很清楚的看到非公平锁和公平锁都继承了Sync,并且它们存在两个相同的方法不同的具体实现。

lock方法

当调用lock方法时,会调用sync变量的lock方法,而Lock只是一个抽象类,调用时会根据不同的子类执行不同的方法
在这里插入图片描述

公平锁执行lock方法

公平锁会执行如下的方法:

    public final void acquire(int arg) {if (// 尝试获取锁。。。(1)!tryAcquire(arg) &&//如果获取锁失败将执行该方法.。。。(2)acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}

查看(1):

        protected final boolean tryAcquire(int acquires) {// 获取当前线程final Thread current = Thread.currentThread();//获取状态码stateint c = getState();//如果状态码为0表示锁是空闲的if (c == 0) {// 判断等待队列是否为nullif (!hasQueuedPredecessors() &&//如果为null线程通过CAS修改state变量compareAndSetState(0, acquires)) {//如果修改成功设置持有锁的线程返回truesetExclusiveOwnerThread(current);return true;}}// 如果当前的线程就是持有锁的线程,就表示该线程重入这个锁else if (current == getExclusiveOwnerThread()) {//修改state变量int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded")//通过CAS将state修改为重入的次数setState(nextc);return true;}return false;}}

我们进入以上代码的一些方法中查看:
该方法主要是判断队列中有没有其他要竞争锁的线程,如果存在当前线程就需要入队按照竞争锁的顺序来获取锁。

 public final boolean hasQueuedPredecessors() {Node t = tail; // Read fields in reverse initialization orderNode h = head;Node s;return//如果等待队列的头节点就是尾结点,因为头节点是当前持有锁的线程,那么此时没有其他竞争锁的线程,当前线程有资格竞争锁h != t &&((s = h.next) == null || s.thread != Thread.currentThread());}

设置当前持有锁的线程:

    protected final void setExclusiveOwnerThread(Thread thread) {exclusiveOwnerThread = thread;}

如果方法1返回true,则表明线程成功获取到了锁,如果返回false,则表示竞争锁失败,就会执行方法2,方法2中的参数调用了一个方法该方法会将当前线程包装成一个结点放到等待队列的尾部

    private Node addWaiter(Node mode) {Node node = new Node(Thread.currentThread(), mode);// Try the fast path of enq; backup to full enq on failureNode pred = tail;if (pred != null) {node.prev = pred;if (compareAndSetTail(pred, node)) {pred.next = node;return node;}}enq(node);return node;}

然后执行以下方法,该方法会根据线程访问的顺序也即等待队列的顺序竞争锁

    final boolean acquireQueued(final Node node, int arg) {boolean failed = true;try {boolean interrupted = false;//线程进入自旋状态for (;;) {//获取当前入队结点的前驱结点final Node p = node.predecessor();//当前驱结点为头节点时(即前驱结点当前持有了锁),当前线程才有获取锁的资格,当前线程通过CAS获取锁if (p == head && tryAcquire(arg)) {//当前线程获取锁成功后,将当前结点设置为头节点,返回falsesetHead(node);p.next = null; // help GCfailed = false;return interrupted;}//判断前驱结点的状态,如果状态为撤销,直接跳过if (shouldParkAfterFailedAcquire(p, node) &&//判断线程是否被中断parkAndCheckInterrupt())interrupted = true;}} finally {if (failed)cancelAcquire(node);}}
//通过方法二的返回值,判断当前线程的中断位,可以响应中断static void selfInterrupt() {Thread.currentThread().interrupt();}
公平锁lock流程图

在这里插入图片描述

非公平锁执行lock方法

     final void lock() {//直接CAS修改state状态,尝试获取锁if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());else//竞争锁失败acquire(1);}

竞争锁失败后的逻辑与公平锁的逻辑差不多,只有第一个方法是不同的

    public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}

与公平锁不同的是,其发现state为0时直接CAS修改state获取锁

        final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}

当线程获取不到锁时,会与线程竞争公平锁的逻辑相同,会包装为结点放入等待队列,锁定前驱结点,当前驱结点获取锁时才会尝试再次获取锁,而不是一直在等待队列中尝试获取锁,这样太浪费性能了。

线程获取公平锁和非公平锁的区别

线程调用lock方法获取公平锁时,当知道锁未被持有时,首先就会通过CAS修改state变量尝试获取锁,而非空锁则会判断等待队列中是否存在等待锁的线程,如果不存在会尝试获取锁。后面的逻辑两种则相同,加入等待队列,锁定前驱结点,当前驱节点持有锁时,会尝试获取锁。

至于超时获取锁的方法,大家可以看看源码,只比lock方法增加了一个超时的逻辑。

释放锁

释放锁的逻辑相当简单,用state变量减去当前线程重入锁的此时,使用CAS设置state变量即可

    public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);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;}
http://www.dtcms.com/wzjs/384162.html

相关文章:

  • 婚庆公司网站建设线上营销培训
  • dreamwearver可以做网站吗培训心得体会总结
  • 内蒙能源建设集团网站网络广告营销策略
  • 平面设计素材网站知乎泰州seo
  • 建站公司最新价格企业整站seo
  • win7系统做asp网站哪里有网站推广优化
  • 网站admin密码今日最火的新闻
  • 企业网站推广属于付费推广吗服务器ip域名解析
  • 小说网站防盗做的最好的是小程序开发软件
  • 请简述网站建设的一般流程谷歌浏览器引擎入口
  • 如何把字体导入wordpressseo+网站排名
  • 福田做商城网站建设哪家公司靠谱免费发布广告信息网
  • 网站建设费用是多少钱怎样做一个产品营销方案
  • 免费建立网站论坛青岛seo博客
  • 衡水专业网站制作微信朋友圈广告投放价格表
  • 中小学做课题研究的网站新媒体运营怎么自学
  • 网站建设与管理 教材网站搭建免费
  • 网站构造百度智能建站平台
  • 广告网站建设及推广百度竞价推广方案范文
  • 网站建设最新签约下载app到手机上并安装
  • 政府网站集约化建设情况报告看广告收益的正规平台
  • asp服装商城网站源码高端品牌网站建设
  • 制作网站的程序seo交互论坛
  • 房地产门户百度seo2022新算法更新
  • wap手机网站制作郑州seo排名优化公司
  • 湛江赤坎孵化器网站建设招聘新手小白怎么做跨境电商
  • 做英文网站需要多长时间上海的重大新闻
  • 课程网站建设总体情况企业培训系统app
  • 建湖网站设计推广手段
  • 创建网站用什么语言b2b网站