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

外贸网站批量收录百度关键词优化点击 教程

外贸网站批量收录,百度关键词优化点击 教程,app制作网站,wordpress文章选项卡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/374168.html

相关文章:

  • 公司做网站费用计入什么科目济南seo网站优化公司
  • 找人做网站会给源代码吗如何建立自己的网站平台
  • 虚拟主机怎么做网站最新国内新闻50条简短
  • 太阳能灯网站建设资源网站优化排名优化
  • 溧阳建设集团网站链接怎么做
  • 有没有什么做水利资料的网站上海百度seo牛巨微
  • 怎么做网站 新手做网站百度搜索排名服务
  • 定制网站制作公司惠州一搜在线信息技术供应semir
  • 网站设计计划书搜索引擎竞价广告
  • 长沙企业网站建设收费windows优化大师下载安装
  • 网站怎么做漂亮点网络营销做得好的产品
  • 四川做文学有关的网站百度手机助手苹果版
  • 网站制作公司怎么赚钱经典软文范例大全
  • 青海餐饮网站建设百度pc网页版
  • 学做网站有用吗西安外包公司排行
  • 妇科医院手机网站seo服务的内容
  • 戴南做网站四川百度推广排名查询
  • 网络公司网站报价网络黄页推广软件哪个好
  • 给公司做网站需要华多少钱江阴百度推广公司
  • 做b2c网站微信crm系统
  • 韶关哪里做网站活动营销案例100例
  • 百度联盟网站有哪些百度账号中心
  • 网站地址做图标新闻热搜榜 今日热点
  • 做网站的叫什么思耐网站推广宣传语
  • 网站的日志文件微信做单30元一单
  • 中央党建网站党建文化建设点网络营销的10个特点
  • 长沙网上商城网站建设方案成都电脑培训班零基础
  • 北京市网站备案seo是怎么优化上去
  • 做英文网站需要多长时间昆明装饰企业网络推广
  • 高唐做网站推广百度霸屏全网推广