Java线程公平锁和非公平锁的差异讲解

公平锁,顾名思义,它是公平的,可以保证获取锁的线程按照先来后到的顺序,获取到锁。

非公平锁,顾名思义,各个线程获取到锁的顺序,不一定和它们申请的先后顺序一致,有可能后来的线程,反而先获取到了锁。

在实现上,公平锁在进行lock时,首先会进行tryAcquire()操作。在tryAcquire中,会判断等待队列中是否已经有别的线程在等待了。如果队列中已经有别的线程了,则tryAcquire失败,则将自己加入队列。如果队列中没有别的线程,则进行获取锁的操作。

/**
     * Fair version of tryAcquire. Don't grant access unless
     * recursive call or no waiters or is first.
     **/
    protected final boolean tryAcquire(int acquires) {
      final Thread current = Thread.currentThread();
      int c = getState();
      if (c == 0) {
        if (!hasQueuedPredecessors() &&
          compareAndSetState(0, acquires)) {
          setExclusiveOwnerThread(current);
          return true;
        }
      }
      else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0)
          throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
      }
      return false;
    }

非公平锁,在进行lock时,会直接尝试进行加锁,如果成功,则获取到锁,如果失败,则进行和公平锁相同的动作。

从公平锁和非公平的实现上来看,他们的操作基本相同,唯一的区别在于,在lock时,非公平锁会直接先进行尝试加锁的操作。

当前一个线程完成了锁的使用,并且释放了,而且此时等待队列非空时,如果这是有新线程申请锁,那么,公平锁和非公平锁的表现就会出现差异。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接

(0)

相关推荐

  • Java多线程编程实战之模拟大量数据同步

    背景 最近对于 Java 多线程做了一段时间的学习,笔者一直认为,学习东西就是要应用到实际的业务需求中的.否则要么无法深入理解,要么硬生生地套用技术只是达到炫技的效果. 不过笔者仍旧认为自己对于多线程掌握不够熟练,不敢轻易应用到生产代码中.这就按照平时工作中遇到的实际问题,脑补了一个很可能存在的业务场景: 已知某公司管理着 1000 个微信服务号,每个服务号有 1w ~ 50w 粉丝不等.假设该公司每天都需要将所有微信服务号的粉丝数据通过调用微信 API 的方式更新到本地数据库. 需求分析 对此

  • Java多线程实战之单例模式与多线程的实例详解

    1.立即加载/饿汉模式 // 立即加载/饿汉模式 public class MyObject { private static final MyObject myObject = new MyObject(); private MyObject() { } public static MyObject getInstance() { return myObject; } } 立即加载/饿汉模式是在类创建的同时已经创建好一个静态的对象供系统使用,不存在线程安全问题 2.延迟加载/懒汉模式 // 延

  • java基于C/S结构实现多线程聊天室

    本文实例为大家分享了java基于C/S结构实现多线程聊天室的具体代码,供大家参考,具体内容如下 主要实现的功能: 服务器端建立ServerSocket阻塞监听来自客户端的Socket连接,并为之开辟一个新的线程 读取来自该连接的数据,广播每一个客户端数据,这里简单地使用一个链表保存所有来自客户端的所有Socket连接 客户端连接上服务器端后主要有两个线程在工作: 主线程:不断获取键盘的输入并写入该Socket中传输给服务器 副线程:不断从服务器Socket流中读取传来的数据,打印到屏幕上. 服务

  • 实例分析java开启线程的方法

    有时候我们在使用java编程的时候,想启动线程,怎么启动呢,下面来分享一下方法 第一步在我们的电脑上打开eclipse,创建一个java项目,并创建三个类,Test是测试Runnable类实现的多线程程序类,DoSomething是实现Runnable接口的多线程类,TestThread是测试继承Thread类实现的多线程程序类,如下图所示: 第二步我们首先看一下DoSomething类,实现了Runnable接口,成为线程类,并在run方法中进行双层循环打印姓名和数字,如下图所示: 第三步我们

  • java线程池使用后到底要关闭吗

    线程池做什么 网络请求通常有两种形式: 第一种,请求不是很频繁,而且每次连接后会保持相当一段时间来读数据或者写数据,最后断开,如文件下载,网络流媒体等. 另一种形式是请求频繁,但是连接上以后读/写很少量的数据就断开连接.考虑到服务的并发问题,如果每个请求来到以后服务都为它启动一个线程,那么这对服务的资源可能会造成很大的浪费,特别是第二种情况. 因为通常情况下,创建线程是需要一定的耗时的,设这个时间为T1,而连接后读/写服务的时间为T2,当T1>>T2时,我们就应当考虑一种策略或者机制来控制,使

  • Java实现指定线程执行顺序的三种方式示例

    本文实例讲述了Java实现指定线程执行顺序的三种方式.分享给大家供大家参考,具体如下: 方法一:通过共享对象锁加上可见变量来实现. public class MyService { private volatile int orderNum = 1; public synchronized void methodA() { try { while (orderNum != 1) { wait(); } for (int i = 0; i < 2; i++) { System.out.printl

  • Java多线程实战之交叉打印的两种方法

    要求效果:先打印5次"printA-",再打印5次"printB-",每次打印间隔1秒,重复循环20次 方式一:使用wait()和notifyAll()方法 public class MyService { private volatile boolean flag = false; public synchronized void printA() { try { while (flag) { wait(); } for (int i = 0; i < 5;

  • java 线程公平锁与非公平锁详解及实例代码

    java 线程公平锁与非公平锁详解 在ReentrantLock中很明显可以看到其中同步包括两种,分别是公平的FairSync和非公平的NonfairSync.公平锁的作用就是严格按照线程启动的顺序来执行的,不允许其他线程插队执行的:而非公平锁是允许插队的. 默认情况下ReentrantLock是通过非公平锁来进行同步的,包括synchronized关键字都是如此,因为这样性能会更好.因为从线程进入了RUNNABLE状态,可以执行开始,到实际线程执行是要比较久的时间的.而且,在一个锁释放之后,其

  • Java线程公平锁和非公平锁的差异讲解

    公平锁,顾名思义,它是公平的,可以保证获取锁的线程按照先来后到的顺序,获取到锁. 非公平锁,顾名思义,各个线程获取到锁的顺序,不一定和它们申请的先后顺序一致,有可能后来的线程,反而先获取到了锁. 在实现上,公平锁在进行lock时,首先会进行tryAcquire()操作.在tryAcquire中,会判断等待队列中是否已经有别的线程在等待了.如果队列中已经有别的线程了,则tryAcquire失败,则将自己加入队列.如果队列中没有别的线程,则进行获取锁的操作. /** * Fair version o

  • ​​​​​​​Java公平锁和非公平锁的区别

    目录 正文 应用场景 公平和非公平锁代码演示 执行流程分析 公平锁执行流程 非公平锁执行流程 优缺点分析 总结 前言: 从公平的角度来说,Java 中的锁总共可分为两类:公平锁和非公平锁.但公平锁和非公平锁有哪些区别?孰优孰劣呢?在 Java 中的应用场景又有哪些呢?接下来我们一起来看. 正文 公平锁:每个线程获取锁的顺序是按照线程访问锁的先后顺序获取的,最前面的线程总是最先获取到锁.非公平锁:每个线程获取锁的顺序是随机的,并不会遵循先来先得的规则,所有线程会竞争获取锁.  举个例子:公平锁就像

  • 图解Java ReentrantLock公平锁和非公平锁的实现

    目录 概述 RenentrantLock原理概述 非公平锁实现 演示 加锁原理 释放锁原理 公平锁实现 演示 原理实现 总结 概述 ReentrantLock是Java并发中十分常用的一个类,具备类似synchronized锁的作用.但是相比synchronized, 它具备更强的能力,同时支持公平锁和非公平锁. 公平锁: 指多个线程按照申请锁的顺序来获取锁,线程直接进入队列中排队,队列中的第一个线程才能获得锁. 非公平锁: 多个线程加锁时直接尝试获取锁,能抢到锁到直接占有锁,抢不到才会到等待队

  • ReentrantLock源码详解--公平锁、非公平锁

    问题 (1)重入锁是什么? (2)ReentrantLock如何实现重入锁? (3)ReentrantLock为什么默认是非公平模式? (4)ReentrantLock除了可重入还有哪些特性? 简介 Reentrant = Re + entrant,Re是重复.又.再的意思,entrant是enter的名词或者形容词形式,翻译为进入者或者可进入的,所以Reentrant翻译为可重复进入的.可再次进入的,因此ReentrantLock翻译为重入锁或者再入锁. 重入锁,是指一个线程获取锁之后再尝试获

  • Java concurrency之非公平锁_动力节点Java学院整理

    获取非公平锁(基于JDK1.7.0_40) 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在"尝试获取锁的机制不同".简单点说,"公平锁"在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而"非公平锁"在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁). 1. lock() lock()在ReentrantLock.java的NonfairSync类

  • 三道java新手入门面试题,通往自由的道路--锁+Volatile

    目录 1. 你知道volatile是如何保证可见性吗? 小结: 2. 悲观锁和乐观锁可以讲下你的理解吗? 3. 你还知道什么其他的锁吗? 总结 1. 你知道volatile是如何保证可见性吗? 我们先看一组代码: public class VolatileVisibleDemo { public static boolean initFlag = false; public static void main(String[] args) { new Thread(new Runnable() {

  • java高并发的ReentrantLock重入锁

    目录 synchronized的局限性 ReentrantLock ReentrantLock基本使用 ReentrantLock是可重入锁 ReentrantLock实现公平锁 ReentrantLock获取锁的过程是可中断的 tryLock无参方法 tryLock有参方法 ReentrantLock其他常用的方法 获取锁的4种方法对比 总结 synchronized的局限性 synchronized是java内置的关键字,它提供了一种独占的加锁方式.synchronized的获取和释放锁由j

  • 详解Java ReentrantLock可重入,可打断,锁超时的实现原理

    目录 概述 可重入 可打断 锁超时 概述 前面讲解了ReentrantLock加锁和解锁的原理实现,但是没有阐述它的可重入.可打断以及超时获取锁失败的原理,本文就重点讲解这三种情况.建议大家先看下这篇文章了解下ReentrantLock加锁的基本原理,图解Java ReentrantLock公平锁和非公平锁的实现. 可重入 可重入是指一个线程如果获取了锁,那么它就是锁的主人,那么它可以再次获取这把锁,这种就是理解为重入,简而言之,可以重复获取同一把锁,不会造成阻塞,举个例子如下: @Test p

  • java 线程池存在的意义

    目录 前言 创建线程 继承Thread 实现Runnable接口 实现Callable接口 线程池 小结 前言 再次之前我已经花费大量篇幅介绍了Java原声锁和Lock锁.在文章中提到偏向送.轻量级锁.重量级锁.公平锁.非公平锁.自旋锁.自适应自旋锁.分布式锁.分段锁等等锁.所有的锁都是为了解决一个问题应运而生的那就是并发.而产生并发的原因是CPU的发展导致我们程序多线程运行.在代码中我们也经常通过多线程来提高产品的吞吐量. 在锁章节中我们也是通过多线程案例模拟锁的产生的.那么Java领域中有哪

随机推荐