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时,非公平锁会直接先进行尝试加锁的操作。
当前一个线程完成了锁的使用,并且释放了,而且此时等待队列非空时,如果这是有新线程申请锁,那么,公平锁和非公平锁的表现就会出现差异。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。如果你想了解更多相关内容请查看下面相关链接
相关推荐
-
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领域中有哪
随机推荐
- PHP网站建设的流程与步骤分享
- 自动删除超过10天的文件及文件夹的vbs代码
- java 学习笔记(入门篇)_java的基础语法
- 从别人那拷下来的几点Session使用的经验
- 微信小程序 列表的上拉加载和下拉刷新的实现
- PHP弹出对话框技巧详细解读
- JSP使用自定义标签防止表单重复提交的方法
- 利用Aspose.Word控件实现Word文档的操作
- Android 动画之RotateAnimation应用详解
- jquery获取点击控件的绝对位置简单实例
- javascript 获取函数形参个数
- Android自定义viewgroup可滚动布局 GestureDetector手势监听(5)
- Pandas 数据处理,数据清洗详解
- 使用Python计算玩彩票赢钱概率
- iOS 导航栏自带页面右滑pop使用示例
- 常用的 JS 排序算法 整理版
- 小米推送Java代码
- Android自定义View之绘制圆形头像功能
- C语言通讯录实例分享
- Vue-Router的使用方法