Java AQS如何实现非公平锁 5C

最近看了AQS的源码 但是看完之后有很多问题

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

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    if (ws == Node.SIGNAL)
        /*
         * This node has already set status asking a release
         * to signal it, so it can safely park.
         */
        return true;
    if (ws > 0) {
        /*
         * Predecessor was cancelled. Skip over predecessors and
         * indicate retry.
         */
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {
        /*
         * waitStatus must be 0 or PROPAGATE.  Indicate that we
         * need a signal, but don't park yet.  Caller will need to
         * retry to make sure it cannot acquire before parking.
         */
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}

这是自旋请求资源的方法,但是shouldParkAfterFailedAcquire()方法中,可以得知,在队列中等待的线程,基本都会被park,然后来看release()

public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}

unparkSuccessor将会唤醒后继节点,但是只唤醒了一个,所以我产生了一个疑问,如果只唤醒了一个线程,那么用aqs实现非公平锁,在tryRelease中直接抢锁,但是抢锁失败后,加入队列中,仍然需要按照顺序被唤醒,还是不是完完全全的非公平,但是总觉得是不是有问题,请大神指点我一下

1个回答

先尝试去获取锁,再调用非公平锁

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
java公平锁,非公平锁,CAS,AQS的一些事情
PS:该文章是借鉴掘金的 石衫的架构笔记  附上借鉴的所有链接: 大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?【石杉的架构笔记】 大白话聊聊Java并发面试问题之谈谈你对AQS的理解?【石杉的架构笔记】 大白话聊聊Java并发面试问题之公平锁与非公平锁是啥?【石杉的架构笔记】 谈到公平锁和非公平锁,首先要引入2个概念。一个是CAS,一个是AQS。 CAS:全名叫做C...
Java中的公平锁和非公平锁实现详解
Java语言中有许多原生线程安全的数据结构,比如`ArrayBlockingQueue`、`CopyOnWriteArrayList`、,它们的实现方式并非通过`synchronized`关键字,而是通过`java.util.concurrent.locks.ReentrantLock`来实现。 本博客着重讲述ReentrantLock的可重入性原理、公平/非公平实现、内存可见性原理。
java多线程的公平锁和非公平锁
java多线程 ReentrantLock.lock 公平锁 非公平锁。
java重入锁、公平锁和非公平锁
锁的重入是指同一个线程可以多次获取同一个锁,synchronize是隐式的可重入锁,ReentrantLock通过代码实现了锁的重入: final boolean nofairTryAcquire(int acquires){ final Thread current=Thread.currentThread();...
ReentrantLock与公平锁、非公平锁实现
前言最近开始读JDK源码,所有心得准备总结成一个专栏,JDK Analysis系列的第一篇,就从万众瞩目的ReentrantLock开始吧,而谈到ReentrantLock,就不得不说AQS,它是AbstractQueuedSynchronizer类的简称,Doug Lea上神在JDK1.5将其引入,这才有了现在的并发包java.util.concurrent,所以要理解ReentrantLock的
Java多线程 -- 公平锁和非公平锁
在java的锁机制中,公平和非公平的参考物是什么,个人而言觉得是相对产生的结果而立,简单的来说,如果一个线程组里,能保证每个线程都能拿到锁,那么这个锁就是公平锁。相反,如果保证不了每个线程都能拿到锁,也就是存在有线程饿死,那么这个锁就是非公平锁。本文围绕ReenTrantLock来讲。 实现原理 那如何能保证每个线程都能拿到锁呢,队列FIFO是一个完美的解决方案,也就是先进先出,java的Re...
java之ReentrantLock公平锁和非公平锁
大多数情况下,大家可能都会选择使用synchronized来加锁,ReentrantLock确实是一种高级加锁工具,在确实需要一些 synchronized 所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。 以下实现公平锁和非公平锁,公平锁在性能上会多消耗点 package com.cmcc.web.test.lock; import java.util
公平锁/非公平锁分析,从await/singl分析AQS
大家推荐个靠谱的公众号程序员探索之路,公众号内点击网赚获取彩蛋,大家一起加油,这个公众号已经接入图灵​ 前言:看这篇文章之前需要看https://blog.csdn.net/yueloveme/article/details/86483781,下文有些名词和这篇文章统一 1.ReentrantLock 的公平锁和非公平锁 代码上的区别 非公平锁: 这里直接...
ReentrantLock 公平锁和非公平锁
对于ReentrantLock,一般我们在调用无参构造函数的时候,构造的是非公平锁,当前类也存在一种可以指定锁类型的构造方法,即 ReentrantLock(boolean fair),ReentrantLock锁的实现是通过内部类FairSync和NonfairSync继承AQS实现的。 我们今天主要讨论下这两个内部类,从而探讨下代码级别是如何实现公平锁和非公平锁的。 先看Reentra...
并发编程--公平锁和非公平锁
在上一篇博客并发编程--互斥锁ReentrantLock中我们简单介绍了一下ReentrantLock,ReentrantLock提供了公平锁和非公平锁的机制,我们已经了解到ReentrantLock提供了一个FIFO线程队列,对于公平锁来说,当锁是可获取时首先让FIFO队列中的线程获取锁,当前线程需要进FIFO队列进行等待;对于非公平锁来说,当锁是可获取时,这个线程可以直接获取锁,不用在FIFO
ReentrantLock公平锁和非公平锁
公平锁是指多个线程在等待同一个锁时,必须按照申请锁的先后顺序来一次获得锁。 公平锁的好处是等待锁的线程不会饿死,但是整体效率相对低一些;非公平锁的好处是整体效率相对高一些,但是有些线程可能会饿死或者说很早就在等待锁,但要等很久才会获得锁。其中的原因是公平锁是严格按照请求所的顺序来排队获得锁的,而非公平锁时可以抢占的,即如果在某个时刻有线程需要获取锁,而这个时候刚好锁可用,那么这个线程会直接抢占,...
公平锁 VS 非公平锁
公平锁: 1.概念 公平锁是指多个线程按照申请锁的顺序来获取锁,线程直接进入队列中排队,队列中的第一个线程才能获 得锁 2.优点 公平锁的优点是等待锁的线程不会饿死 3.缺点 缺点是整体吞吐效率相对非公平锁要低,等待队列中除第 一个线程以外的所有线程都会阻塞,CPU唤醒阻塞线程的开销比非公平锁大。 非公平锁: 1.概念 非公平锁是多个线程加锁时直接尝试获取锁,获取不到才会到等待队...
ReentrantLock的公平锁和非公平锁
今天学习了一下关于Lock中的公平锁和非公平锁,就想总结一下这两种之间的区别。具体有不对的地方欢迎指正。     首先锁Lock分为"公平锁"和"非公平锁",公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,即呢就是先来先得的FIFO先进先顺序。非公平锁就是获取锁的抢占机制,是随机获取锁的,那这俩货的区别就在这个地方了,非公平锁先来的不一定先得到锁,这就会造成某些线程可能一直拿不到锁,结果
公平锁 非公平锁 使用场景
公平锁 非公平锁 使用场景. 公平与非公平 这个概念是针对锁的获取的,在绝对时间上,先对锁进行获取的请求一定先满足,那么这个锁是公平的,反之就是不公平的。公平锁的获取就是等待时间最长的线程最先获取锁,也就是锁获取是顺序的。但是公平锁的机制往往效率不高。 但是非公平锁有可能导致:一直获取不到锁的现象: 饿死:一些客户端不能获得服务,而其他客户端却可以;违反了公平原则---服务
公平锁和非公平锁(demo)
java多线程附录
公平锁 非公平锁
今天偶然看ArrayBlockingQueue源码时,发现其中有关于公平锁 非公平锁。也趁此学习一下什么叫做公平锁 非公平锁。 下面是ArrayBlockingQueue的部分源码:  public ArrayBlockingQueue(int capacity) {         this(capacity, false);     }  public ArrayBlockingQu
公平锁和非公平锁
公平锁,顾名思义,它是公平的,可以保证获取锁的线程按照先来后到的顺序,获取到锁。 非公平锁,顾名思义,各个线程获取到锁的顺序,不一定和它们申请的先后顺序一致,有可能后来的线程,反而先获取到了锁。 在实现上,公平锁在进行lock时,首先会进行tryAcquire()操作。在tryAcquire中,会判断等待队列中是否已经有别的线程在等待了。如果队列中已经有别的线程了,则tryAcquire失败,...
公平锁和非公平锁的区别
1.公平锁:顾名思义–公平,大家老老实实排队。 2.非公平锁:只要有机会就尝试抢占资源 3.非公平锁的弊端:可能导致后面排队等待的线程等不到相应的CPU资源,从而引起线程饥饿。 ...
公平锁和非公平锁及信号量
Synchronized是线程执行完毕以后释放资源,这里我们看不到手动锁住临界区和释放临界区的操作,而重入锁可以做到这一点。 重入锁使用 java.util.concurrent.locks.ReentrantLock 先放代码帮助理解 import java.util.concurrent.locks.Condition; import java.util.concurrent.lo...
Java中ReentrantLock的公平锁和非公平锁
了解 Java 中 ReentrantLock 的程序员都知道,ReentrantLock 的核心组成是队列同步器 AbstractQueuedSynchronizer。而ReentrantLock中定义了内部抽象类Sync,又定义了NonfairSync和FairSync,这两者分别是非公平锁和公平锁的组件。
zookeeper实现分布式锁(公平锁|非公平锁)
无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里以跳转到教程。 zk实现分布式锁,此类资源很多,但是能经得起的推荐的却很少,同时也看了看twitter实现的分布式锁,很吊。但是twitter中封装的zookeepre工具包,内容有点多,如果我们直希望使用分布式,就显得略微冗重了。因此自己实现了...
Java多线程(PART XXIV)公平锁和非公平锁
定义公平锁:公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的。示例代码:import java.util.concurrent.locks.ReentrantLock; import java.lang.Thread; class MyService{ private ReentrantLock lock; public MyService(boolean isFair){
java并发库 Lock 公平锁和非公平锁
          jdk1.5并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,关于两者区别,java并发编程实践里面有解释 公平锁:   Threads acquire a fair lock in the order in which they requested it 非公平锁:a nonfair lock permits ba...
Java多线程Lock对象之公平锁和非公平锁
公平锁和非公平锁
AQS中非公平锁的实现原理简介
先了解非公平锁,公平锁自然就很简单了 Lock lock =new ReentrantLock(); lock.lock(); 在ReentrantLoc类中,有Sync,FairSync,NonfaiSync 类图如下,   首先,public void lock() { sync.lock(); }调用sync的lock,sync会调用子类公平锁或者非公平锁的lock。 ...
JAVA并发-ReentrantLock怎么实现非公平锁和公平锁
非公平:1.调用lock()方法时,首先去通过CAS尝试设置锁资源的state变量,如果设置成功,则设置当前持有锁资源的线程为当前请求线程2.调用tryAcquire方法时,首先获取当前锁资源的state变量,如果为0,则通过CAS去尝试设置state,如果设置成功,则设置当前持有锁资源的线程为当前请求线程以上两步都属于插队现象,可以提高系统吞吐量公平:1.调用lock()方法时,不进行CAS尝试...
ReentrantLock的非公平锁和公平锁的实现原理
非公平锁 因为之前已经分析过AQS,ReentranLock是利用一个实现了AQS的NonfairSync来获取非公平锁。所以只需关注NonfairSync的tryAcquire的实现。       获取锁(nonfairTryAcquire方法定义在Sync内部类中)   获取锁成功分为两种情况,第一个if判断AQS的state是否等于0,表示锁没有人占有。接着,hasQueu...
线程公平锁和非公平锁使用
-
重入锁和自旋锁(公平锁及非公平锁)
公平锁,就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己 非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式 前言重入锁(ReentrantLock)是一种递归无阻塞的同步机制。 重入锁,也叫做递归锁,指的是同一线程
重入锁+读写锁+公平锁+非公平锁
synchronized关键字可以实现线程间的同步互斥工作。Lock对象锁是一种完成同步互斥工作的一个更优秀机制。它具有比synchronized更为强大的功能,并且有嗅探锁定、多路分支等功能。重入锁在需要进行同步的代码部分添加锁定,但不要忘记最后一定要释放锁定,不然会造成锁永远无法释放,其他线程永远进不来的结果。UseReentrantLock.javaimport java.util.conc...
源码角度来分析ReentrantLock是怎么利用AQS来实现公平锁,和非公平锁
ReentrantLock这篇文章是从JDK8的ReentrantLock源码角度来分析ReentrantLock是怎么利用AQS来实现公平锁,和非公平锁的。所以前提需要理解AQS。 /** * A reentrant mutual exclusion {@link Lock} with the same basic * behavior and semantics as t
锁- 公平锁和非公平锁的差异
 java http http
java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列
前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器。它是构建锁或者其他同步组件的基础框架(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),JUC并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。它是JUC并发包中的核心基础组件 本文所有源码基于JDK9 Reen...
Java 公平锁与非公平锁
公平锁与非公平锁: 锁Lock分为公平锁和非公平锁。 公平锁:表示线程获取锁的顺序是按照加锁的顺序来分配的,及先来先得,先进先出的顺序。 非公平锁:表示获取锁的抢占机制,是随机获取锁的,和公平锁不一样的就是先来的不一定能拿到锁, 有可能一直拿不到锁,所以结果不公平。 公平锁实例: public class Service { private ReentrantLock lock; pub...
Java实现的公平锁
参考文献:http://tutorials.jenkov.com/java-concurrency/starvation-and-fairness.html 使用公平锁的原因是为了防止饥饿,导致饥饿的原因如下: 1、高优先级线程吞噬所有的低优先级线程的CPU时间(高优先级任务会获取更多的时间片)。 2、线程被永久堵塞在一个等待进入同步块的状态,因为其他线程总是能在它之前持续地对该同
一种公平锁的java实现
利用队列来实现公平锁public class Lock { private Queue<String> intrestedQueue = new ArrayDeque<String>();//感兴趣的线程队列 private volatile String turn;//轮到哪个线程执行 public void lock() { Thread currentTh
辨别公平锁、非公平锁、乐观锁、悲观锁
公平锁 先到先得,优先处理先到的进程 非公平锁 所有进程到达时都会尝试直接获取锁,如果失败则会进入等待序列 乐观锁 每次去拿数据的时候都认为别人不会修改,所以不会上锁(适用多读少写的场景),实现:通过记录不同时间点的版本数据,并在更新的时候检测数据是否冲突。 悲观锁 每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁(适用多写少读的场景),实现:采用sychronized关键字等独...
多线程-内置锁、显式锁、公平锁、非公平锁
synchronized :代码简洁,隐式支持可重新获得锁 synchronized就不实现了,大家可以自行尝试 Lock:获取锁可以被中断,超时获取锁,尝试获取锁 Lock锁的运用更加灵活 这里我们用可重入锁的实例来实现:Lock lock = new ReentrantLock();(注意,这里我们可以观察ReentrantLock里面) 这一段话意味着,我们在构造锁实例的时候...
多线程-ReentrantLock源码分析(公平锁和非公平锁)
什么是公平性锁: 按照线程请求锁的顺序来获取锁。 什么是非公平性锁: 获取锁的线程不是按照先来后到的顺序获取,而是抢夺式获取锁。 ReentrantLock源码分析: 继承关系: ReentrantLock实现了Lock接口。该接口提供了一些通用的加锁解锁操作。 void lock(): 加锁操作,得不到则阻塞直至得到锁。 void lockInterruptibly() throws Int...
真的理解公平锁和非公平锁嘛?
之前一直对公平锁和非公平锁的概念不是特别清楚,简单理解为只要当前资源被加锁,之后的请求都会搁置到队列中公平锁就是严格按照FIFO(先进先出)的规矩办事。非公平锁就是不遵守这个先进先出的规矩,恶性竞争资源。在看AQS(AbstractQueuedSyncronizer)的源码中打破这种不太准确的认知. 接下来我会用ReentrantLock的源码配合着阐述我理解的公平锁和非公平锁。 公平锁: Fai...
相关热词 c# 去空格去转义符 c#用户登录窗体代码 c# 流 c# linux 可视化 c# mvc 返回图片 c# 像素空间 c# 日期 最后一天 c#字典序排序 c# 截屏取色 c#中的哪些属于托管机制