公平锁和非公平锁的详解

article/2025/9/27 6:16:02
  • 公平锁

    加锁时考虑排队等待问题,按照申请锁的顺序,按照FIFO规则,先申请的线程先取得锁,其他线程进入队列等待锁的释放,当锁释放后,在队头的线程被唤醒。

  • 非公平锁

    加锁时不考虑排队等待问题,直接尝试获取锁。如果此时恰好锁处于unlock,则不管有没有其他线程在等待,直接拿到锁;否则就转化成公平锁的模式,进入队列等待。

  • 两者对比

    非公平锁性能比公平锁高5~10倍,因为公平锁需要频繁唤醒队列中的线程,比较消耗资源

    公平锁保证了线程按照先后顺序执行,但效率较低。

    非公平锁效率比较高,但是非公平锁让获取锁的时间变得更加不确定,可能会导致在阻塞队列中的线程长期处于饥饿状态

  • 一张很形象的图

tupian.jpg

  • 验证代码

    package top.ijuer.JUC.lock;import org.junit.Test;import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;public class TestReentrantLock {private static Lock fairLock = new ReentrantLockMine(true);private static Lock unfairLock = new ReentrantLockMine(false);@Testpublic void unfair() throws InterruptedException {testLock("非公平锁", unfairLock);}@Testpublic void fair() throws InterruptedException {testLock("公平锁", fairLock);}private void testLock(String type, Lock lock) throws InterruptedException {System.out.println(type);for (int i = 0; i < 5; i++) {Thread thread = new Thread(new Job(lock)){public String toString() {return getName();}};thread.setName("" + i);thread.start();}Thread.sleep(11000);}private static class Job implements Runnable{private Lock lock;public Job(Lock lock) {this.lock = lock;}public void run() {for (int i = 0; i < 2; i++) {lock.lock();try {Thread.sleep(1000);System.out.println("获取锁的当前线程[" + Thread.currentThread().getName() + "], 同步队列中的线程" + ((ReentrantLockMine)lock).getQueuedThreads() + "");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}}private static class ReentrantLockMine extends ReentrantLock {  //重新实现ReentrantLock类是为了重写getQueuedThreads方法,便于我们试验的观察public ReentrantLockMine(boolean fair) {super(fair);}@Overrideprotected Collection<Thread> getQueuedThreads() {   //获取同步队列中的线程List<Thread> arrayList = new ArrayList<>(super.getQueuedThreads());Collections.reverse(arrayList);return arrayList;}}
    }
    

image-20200220002919940.png

通过结果可以证明,非公平锁在释放锁完成后会立即尝试第二次抢锁,并且因为其他线程处于挂起状态,所以第二次抢锁大概率会成功,当然只是概率比较大,并不是绝对,比如线程2第二次抢锁就没有抢过线程3,此时抢锁失败的线程2进入队列等待。

公平锁释放的时候并没有尝试去抢锁,乖乖的进入队列等待,让队列头的线程去获得这把锁。

  • 拓展

    synchronized 也属于非公平锁


http://chatgpt.dhexx.cn/article/X1S9TM6D.shtml

相关文章

可重入锁的理解及公平锁和非公平锁的具体实现

可重入锁 首先结合以下两个例子理解以下可重入锁的概念。 /*** 可重入锁:* 1、可重复可递归调用的锁&#xff0c;在外层使用锁之后&#xff0c;在内层仍然可以使用&#xff0c;并且不发生死锁&#xff0c;这样的锁就叫做可重入锁。* 2、是指在同一个线程在外层方法获取锁的时…

公平锁与非公平锁的核心原理

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章是关于并发编程中AQS的独占模式和共享模式。 本篇文章记录的基础知识&#xff0c;适合在学Java的小白&#xff0c;也适合复习中&#xff0c;面试中的大佬&#x1…

公平锁和非公平锁介绍,为什么要“非公平”?

什么是公平和非公平 公平锁指的是按照线程请求的顺序&#xff0c;来分配锁&#xff1b;而非公平锁指的是不完全按照请求的顺序&#xff0c;在一定情况下&#xff0c;可以允许插队。但需要注意这里的非公平并不是指完全的随机&#xff0c;不是说线程可以任意插队&#xff0c;而…

图解ReentrantLock公平锁和非公平锁实现

概述 ReentrantLock是Java并发中十分常用的一个类&#xff0c;具备类似synchronized锁的作用。但是相比synchronized, 它具备更强的能力&#xff0c;同时支持公平锁和非公平锁。 公平锁&#xff1a; 指多个线程按照申请锁的顺序来获取锁&#xff0c;线程直接进入队列中排队&a…

Java面试突击:公平锁和非公平锁有什么区别?

从公平的角度来说&#xff0c;Java 中的锁总共可分为两类&#xff1a;公平锁和非公平锁。但公平锁和非公平锁有哪些区别?孰优孰劣呢?在 Java 中的应用场景又有哪些呢?接下来我们一起来看。 正文公平锁&#xff1a;每个线程获取锁的顺序是按照线程访问锁的先后顺序获取的&am…

浅谈ReentrantLock的公平锁和非公平锁的区别

前言 最近在看java并发编程这本书&#xff0c;已经看了点ReentrantLock的源码&#xff0c;以及之前有面试官问&#xff0c;公平锁和非公平锁有啥区别&#xff0c;我就只是从源码层面说了一下区别&#xff0c;但在性能上也有区别&#xff0c;今天就来说道说道。 公平与非公平 …

aqs原理初探以及公平锁和非公平锁实现

深入理解AQS 一&#xff0c;AQS1&#xff0c;ReentrantLock2&#xff0c;CAS3&#xff0c;AbstractQueuedSynchronizer3.1&#xff0c;FairSync3.2&#xff0c;NofairSync3.3&#xff0c;AQS中几个重要的相关参数3.4&#xff0c;Node 一&#xff0c;AQS AbstractQueuedSynchro…

图解ReentrantLock底层公平锁和非公平锁实现原理

&#x1f4bb;在面试或者日常开发当中&#xff0c;经常会遇到公平锁和非公平锁的概念。 两者最大的区别如下&#x1f447; 1️⃣ 公平锁&#xff1a;N个线程去申请锁时&#xff0c;会按照先后顺序进入一个队列当中去排队&#xff0c;依次按照先后顺序获取锁。就像下图描述的上…

ReentrantLock之公平锁和非公平锁详解

ReentrantLock是一个互斥锁&#xff0c;它具有synchronized相同的能力&#xff1b;但相比之下&#xff0c;ReentrantLock扩展性更强&#xff0c;比如实现了公平锁。 下面详细拆解下ReentrantLock的公平锁和非公平锁的实现。 JDK版本&#xff1a;1.8.0_40 公平锁 先看Reentr…

ReentrantLock中公平锁和非公平锁的区别

目录 背景知识 ReentrantLock的组成 概述 公平锁示意图 非公平锁示意图 源码解读 非公平锁 公平锁 代码对比 问题 知识扩展 tryLock方法 参考资料 背景知识 ReentrantLock的组成 首先看下ReentrantLock的组成结构。 公平锁和非公平锁主要是通过内部类FairSync和…

公平锁和非公平锁

Reentrant Re entrant&#xff0c;Re是重复、又、再的意思&#xff0c;entrant是enter的名词或者形容词形式&#xff0c;翻译为进入者或者可进入的&#xff0c;所以Reentrant翻译为可重复进入的、可再次进入的&#xff0c;因此ReentrantLock翻译为重入锁或者再入锁。 公平锁…

阿里面试官:说一下公平锁和非公平锁的区别?

点赞再看&#xff0c;养成习惯&#xff0c;微信搜索【三太子敖丙】关注这个互联网苟且偷生的工具人。 本文 GitHub https://github.com/JavaFamily 已收录&#xff0c;有一线大厂面试完整考点、资料以及我的系列文章。 前言 上次我们提到了乐观锁和悲观锁&#xff0c;那我们知道…

Ubuntu 手动安装 JDK8

文章目录 1. 下载2. 解压安装3. 配置环境变量 1. 下载 先去官网下载合适的版本&#xff0c;官网&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ 通过下载页面获取到下载链接后&#xff0c;可以直接在Ubuntu上使用wget下载&#xff0c;也可以先下载…

centos8安装jdk教程

文章目录 一、安装二、配置环境变量三.验证 一、安装 1、查看JDK软件包列表 yum search java | grep -i --color jdk2、选择版本安装 yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel或者如下命令安装jdk8所有文件 yum install -y java-1.8.0-openjdk*二、配置…

Java - JDK8安装及配置环境变量教程

Java - JDK8安装及配置环境变量教程 一、安装JDK教程 甲骨文官网下载JDK版本&#xff1a;windows64下载地址 下载完成后开始安装JDK&#xff1a;双击打开 点击下一步&#xff1a; 若不需要自定义路径&#xff0c;则安装到默认路径即可&#xff08;安装的路径需记住&#xff0…

JDK8安装和环境配置

JDK8的安装和环境配置 一、JDK8下载二、安装三、环境配置 一、JDK8下载 官网下载&#xff1a; https://www.oracle.com/java/technologies/downloads/#java8-windows 二、安装 打开安装&#xff0c;一直下一步即可&#xff0c;可以在安装过程中更改安装地址&#xff0c;我放…

Java JDK 8的安装与配置

文章目录 前言1. 安装JDK 8Step1&#xff1a;选择JDK的版本Step2&#xff1a;选择系统平台Step3&#xff1a;下载安装包Step4&#xff1a;开始安装 2. 配置JDK 8Step1&#xff1a;配置“环境变量path” 前言 本教程是在Windows 64位平台上安装JDK 8版本。 1. 安装JDK 8 官网…

JDK8安装与环境配置

前言&#xff1a;在网上看了下JDK的安装与环境配置&#xff0c;发现很多视频以及博客的讲的都很复杂&#xff0c;对初学者很不友好。很多小白看到这些配置步骤都一脸懵&#xff0c;即使一步一步看着操作还是配置失败。这主要是因为很多博主配置了不需要的配置环境&#xff0c;让…

Linux安装JDK8详细图文教程

第一步、获取JDK文件 JDK下载包&#xff1a;直接进入 如果跳转登录页面&#xff0c;注册一个账号登录即可 登录过后文件就下载完成 第二步、上传JDK到服务器 1、创建JDK目录 mkdir -p /developer/env/jdk进入目录 cd /developer/env/jdk2、安装lrzsz&#xff08;用于远程传…

JDK8安装教程(Windows、Ubuntu)

文章目录 下载JDK8在Windows上安装设置环境变量 在Ubuntu上安装 下载JDK8 Linux版&#xff0c;CSDN下载地址 推荐官网下载&#xff08;需要注册&#xff09;&#xff0c;能下到Windows和Ubuntu的最新版 在Windows上安装 双击打开下载好的安装包&#xff0c;点击下一步 点击左…