lesson3.1:java公平锁和非公平锁及读写锁
关于这四种锁的各自情况,网上有很多文章做了介绍,本不想单独开章节介绍,本章只介绍这四种锁的一些源码特点及注意事项。
demo 源码:https://github.com/mantuliu/javaAdvance
首先来看公平锁和非公平锁,我们默认使用的锁是非公平锁,只有当我们显示设置为公平锁的情况下,才会使用公平锁,下面我们简单看一下公平锁的源码,如果等待队列中没有节点在等待,则占有锁,如果已经存在等待节点,则返回失败,由后面的程序去将此线程加入等待队列:
/**
* 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;
}
}
通过上面的代码,我们可以推断,当使用公平锁的情况下,并且同一个线程的执行时间较长时,线程内部进行了多次的锁的获取和释放,效率非常低下,可以参加Lesson8中的demo:
demo Lesson8LockIntPerform:在使用ReentrantLock加非公平锁的情况下100个线程循环下单数为:857239882
demo Lesson8LockIntPerform:在使用ReentrantLock加非公平锁的情况下100个线程循环下单数为:860364303
demo Lesson8LockFairIntPerform:在使用ReentrantLock加公平锁的情况下100个线程循环下单数为:19153640
demo Lesson8LockFairIntPerform:在使用ReentrantLock加公平锁的情况下100个线程循环下单数为:19076567
上面的demo中,在使用公平锁的情况下性能明显降低,非公平锁的性能是公平锁性能的几十倍以上,这和公平锁每次试图占有锁时,都必须先要进等待队列,按照FIFO的顺序去获取锁,因此在我们的实验情景下,使用公平锁的线程进行了频繁切换,而频繁切换线程,性能必然会下降的厉害,这也告诫了我们在实际的开发过程中,在需要使用公平锁的情景下,务必要考虑线程的切换频率。
接下来我们来看一下读写锁,通过看读写锁的实现源码,我们可以发现,读锁和写锁共用同一个等待队列,那么在采用非公平锁的情况下,如果读锁的线程执行时间比较长,并且读锁的并发比较高,那么写锁的线程便永远都拿不到锁,那么实际的情况会不会是这样呢?
demo Lesson3WriteReadLock:此demo的读线程在不断的占用读锁,按照推论,写锁的线程是没有机会获取到锁的,但是实际情况是写锁的线程可以正常的获取到锁,那么是什么原因使得写锁的线程可以获取到锁的了?通过查看源代码,会发现有这样的一个方法:
final boolean apparentlyFirstQueuedIsExclusive() {
Node h, s;
return (h = head) != null &&
(s = h.next) != null &&
!s.isShared() &&
s.thread != null;
}
上面的方法,实现了一个新的读线程获取锁的中断,它会读取等待队列中下一个等待锁的线程,如果它是获取写锁的线程,那么此方法返回为真,调用它的程序会把这个试图获取读锁的线程加入到等待队列,从而终止了读线程一直都在占有锁的情况。
lesson3.1:java公平锁和非公平锁及读写锁的更多相关文章
- java并发库 Lock 公平锁和非公平锁
jdk1.5并发包中ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁或非公平锁,关于两者区别,java并发编程实践里面有解释 公平锁: Threads acquir ...
- Java中的公平锁和非公平锁实现详解
前言 Java语言中有许多原生线程安全的数据结构,比如ArrayBlockingQueue.CopyOnWriteArrayList.LinkedBlockingQueue,它们线程安全的实现方式并非 ...
- Java 公平锁与非公平锁学习研究
最近学习研究了一下Java中关于公平锁与非公平锁的底层实现原理,总结了一下. 首先呢,通过其字面意思,公平与非公平的评判标准就是付出与收获成正比(和社会中的含义差不多一个意思).放到程序中,尤其是 在 ...
- “全栈2019”Java多线程第二十八章:公平锁与非公平锁详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java之ReentrantLock公平锁和非公平锁
在Java的ReentrantLock构造函数中提供了两种锁:创建公平锁和非公平锁(默认).代码如下: public ReentrantLock() { sync = new NonfairSync( ...
- 死磕 java同步系列之ReentrantLock源码解析(一)——公平锁、非公平锁
问题 (1)重入锁是什么? (2)ReentrantLock如何实现重入锁? (3)ReentrantLock为什么默认是非公平模式? (4)ReentrantLock除了可重入还有哪些特性? 简介 ...
- Java并发指南8:AQS中的公平锁与非公平锁,Condtion
一行一行源码分析清楚 AbstractQueuedSynchronizer (二) 转自https://www.javadoop.com/post/AbstractQueuedSynchronizer ...
- Java中的锁-悲观锁、乐观锁,公平锁、非公平锁,互斥锁、读写锁
总览图 如果文中内容有错误,欢迎指出,谢谢. 悲观锁.乐观锁 悲观锁.乐观锁使用场景是针对数据库操作来说的,是一种锁机制. 悲观锁(Pessimistic Lock):顾名思义,就是很悲观,每次去拿数 ...
- Java并发编程锁之独占公平锁与非公平锁比较
Java并发编程锁之独占公平锁与非公平锁比较 公平锁和非公平锁理解: 在上一篇文章中,我们知道了非公平锁.其实Java中还存在着公平锁呢.公平二字怎么理解呢?和我们现实理解是一样的.大家去排队本着先来 ...
随机推荐
- 编程小计——消除Graphics图像边缘颜色不纯(抗锯齿)
在很多时候,我们都要绘制纯色的图片,而用Graphics生成的往往是不纯的,尤其是绘制文字时.比如说绘制纯红色文字,往往R达不到255. C#中默认抗锯齿,给人看起来柔和:但是我们现实中往往用到锯齿. ...
- TODO、FIXME和XXX转载
代码中特殊的注释技术——TODO.FIXME和XXX的用处 // TODO Auto-generated method stub
- spark 操作hbase
HBase经过七年发展,终于在今年2月底,发布了 1.0.0 版本.这个版本提供了一些让人激动的功能,并且,在不牺牲稳定性的前提下,引入了新的API.虽然 1.0.0 兼容旧版本的 API,不过还是应 ...
- 1.tomcat部署项目的几种方式和weblogic部署方式及一点通讯
第一种部署方式: 直接使用myeclipse 找到server服务 添加要部署的项目Add Deployment ,然后选中某个项目,首选Exploded Archive(development ...
- Oracle数据库之PL/SQL游标
1. 游标概念 字面意思是游动的光标,是指向上下文区域的句柄或指针. 在PL/SQL块中执行CRUD操作时,ORACLE会在内存中为其分配上下文区.用数据库语言来描述游标就是:映射在上下文区结果集中一 ...
- Css透明度
全透明代码:{background:transparent} 半透明代码:{filter:alpha(opacity=80);-moz-opacity:0.8;width:auto !importan ...
- PHP自动添加http://头 转换网址为链接
有时候,当我们需要用户输入网址的时候,一般我们会让用户省略掉"http://",当提交完成后用代码自动再加上http://,若有需要,我们 还可将网址转换成链接的形式,类似于众多网 ...
- php __clone实现
<?php class Account { public $balance; public function __construct($balance) { $this->balance ...
- UCOS 请求任务删除函数 及其应用
有时候,如果任务A拥有内存缓冲区或信号量之类的资源,而任务B想删除该任务,这些资源就可能由于没被释放而丢失.在这种情况下,用户可以想法子让拥有这些资源的任务在使用完资源后,先释放资源,再删除自己.用户 ...
- .NET MVC 插件化框架源码
本来想把源码整理了放github上,但最近一直忙,就直接在这里放出来了,还写得不太完整,里面有几个例子,插件上传也没写,只写了插件zip包解压,如果大家在使用中有什么疑问,可以加QQ群:1429391 ...