java lock 信号_java各种锁(ReentrantLock,Semaphore,CountDownLatch)的实现原理

先放结论:主要是实现AbstractQueuedSynchronizer中进入和退出函数,控制不同的进入和退出条件,实现适用于各种场景下的锁。

JAVA中对于线程的同步提供了多种锁机制,比较著名的有可重入锁ReentrantLock,信号量机制Semaphore,队列等待机制CountDownLatch,

通过查看源代码可以,他们都是基于AbstractQueuedSynchronizer实现了自身的功能。

796dfedd20df3334c2a5ec4ac5538cdd.png

对于AbstractQueuedSynchronizer的讲解,可以看上一篇文章,这里就讲解下,如何通过集成AbstractQueuedSynchronizer实现上述的锁机制。

所谓的锁实现,就是对AbstractQueuedSynchronizer中state变量的抢占,谁先抢占并且修改了这个变量值不为0,谁就获得了锁。

AbstractQueuedSynchronizer保留了几个未实现的接口供子类实现。分别是

protected boolean tryAcquire(intarg) {throw newUnsupportedOperationException();

}protected boolean tryRelease(intarg) {throw newUnsupportedOperationException();

}protected int tryAcquireShared(intarg) {throw newUnsupportedOperationException();

}protected boolean tryReleaseShared(intarg) {throw newUnsupportedOperationException();

}

tryAcquire和tryRelease是用于独占锁的获取和释放,tryAcquireShared和tryReleaseShared是共享锁的获取和释放,下面看下他们分别是什么地方被调用。

/*** Acquires in exclusive mode, ignoring interrupts. Implemented

* by invoking at least once {@link#tryAcquire},

* returning on success. Otherwise the thread is queued, possibly

* repeatedly blocking and unblocking, invoking {@link* #tryAcquire} until success. This method can be used

* to implement method {@linkLock#lock}.

*

*@paramarg the acquire argument. This value is conveyed to

* {@link#tryAcquire} but is otherwise uninterpreted and

* can represent anything you like.*/

public final void acquire(intarg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))

selfInterrupt();

}/*** Releases in exclusive mode. Implemented by unblocking one or

* more threads if {@link#tryRelease} returns true.

* This method can be used to implement method {@linkLock#unlock}.

*

*@paramarg the release argument. This value is conveyed to

* {@link#tryRelease} but is otherwise uninterpreted and

* can represent anything you like.

*@returnthe value returned from {@link#tryRelease}*/

public final boolean release(intarg) {if(tryRelease(arg)) {

Node h=head;if (h != null && h.waitStatus != 0)

unparkSuccessor(h);return true;

}return false;

}/*** Acquires in shared mode, ignoring interrupts. Implemented by

* first invoking at least once {@link#tryAcquireShared},

* returning on success. Otherwise the thread is queued, possibly

* repeatedly blocking and unblocking, invoking {@link* #tryAcquireShared} until success.

*

*@paramarg the acquire argument. This value is conveyed to

* {@link#tryAcquireShared} but is otherwise uninterpreted

* and can represent anything you like.*/

public final void acquireShared(intarg) {if (tryAcquireShared(arg) < 0)

doAcquireShared(arg);

}/*** Releases in shared mode. Implemented by unblocking one or more

* threads if {@link#tryReleaseShared} returns true.

*

*@paramarg the release argument. This value is conveyed to

* {@link#tryReleaseShared} but is otherwise uninterpreted

* and can represent anything you like.

*@returnthe value returned from {@link#tryReleaseShared}*/

public final boolean releaseShared(intarg) {if(tryReleaseShared(arg)) {

doReleaseShared();return true;

}return false;

}

在acquire中,如果tryAcquire失败,那么就去等待队列中排队,release中如果tryRelease成功,那么就唤醒下一个等待队列中的线程。

acquireShared中,如果tryAcquireShared失败,那么再次进入循环获取过程,releaseShared中,如果tryReleaseShared成功,那么就唤醒下一个等待队列中的线程。

现在的主要问题是,如何判定上述的tryAcquire、tryRelease、tryAcquireShared和tryReleaseShared的成功和失败,

通过阅读源代码可知:

ReentrantLock是一个线程执行,其他线程等待。

ReentrantLock的实现机制就是:线程lock()时,获取时state变量的值不为0,那么tryAcquire就失败,tryRelease执行完state变量的值==0,表示成功,唤醒等待的线程,否则就是失败。

Semaphore是先分配一定数量的许可证,然后多个线程来抢许可证,抢到就可以执行。

Semaphore的实现机制就是:如果获取时当前state减去申请的信号量数目acquires>0,那么就表示成功,此时 state=state-acquires, 否则失败,释放时,当前释放的信号量不为负数,那么就表示成功,唤醒等待的线程,释放后state=state+acquires.

CountDownLatch是一个线程执行,其他线程等待。

CountDownLatch的实现机制是: 线程如果lock()时,获取时state变量的值不为0,那么tryAcquire就失败,tryRelease执行完state变量的值等于0或者state-1后值等于0,表示成功,唤醒等待的线程,否则就是失败。

ReentrantLock的代码如下:

final boolean nonfairTryAcquire(intacquires) {final Thread current =Thread.currentThread();int c =getState();if (c == 0) {if (compareAndSetState(0, acquires)) {

setExclusiveOwnerThread(current);return true;

}

}else if (current ==getExclusiveOwnerThread()) {int nextc = c +acquires;if (nextc < 0) //overflow

throw new Error("Maximum lock count exceeded");

setState(nextc);return true;

}return false;

}protected final boolean tryRelease(intreleases) {int c = getState() -releases;if (Thread.currentThread() !=getExclusiveOwnerThread())throw newIllegalMonitorStateException();boolean free = false;if (c == 0) {

free= true;

setExclusiveOwnerThread(null);

}

setState(c);returnfree;

}

Semaphore代码如下:

final int nonfairTryAcquireShared(intacquires) {for(;;) {int available =getState();int remaining = available -acquires;if (remaining < 0 ||compareAndSetState(available, remaining))returnremaining;

}

}protected final boolean tryReleaseShared(intreleases) {for(;;) {int current =getState();int next = current +releases;if (next < current) //overflow

throw new Error("Maximum permit count exceeded");if(compareAndSetState(current, next))return true;

}

}

CountDownLatch代码如下:

protected int tryAcquireShared(intacquires) {return (getState() == 0) ? 1 : -1;

}protected boolean tryReleaseShared(intreleases) {//Decrement count; signal when transition to zero

for(;;) {int c =getState();if (c == 0)return false;int nextc = c-1;if(compareAndSetState(c, nextc))return nextc == 0;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Intent.ACTION_MAIN

1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始。比较常用。 Input:nothing Output:nothing 例如&#xff1a; 1 <activity android:name".Main"android:label"string/app_name">2 <intent-filter…

足球预测_预测足球热

足球预测By Aditya Pethe通过阿蒂亚皮特(Aditya Pethe) From September to January every year, football takes over America. Games dominate TV Sunday and Monday nights, and my brother tears his hair out each week over his consistently underperforming fantasy te…

C#的特性Attribute

一、什么是特性 特性是用于在运行时传递程序中各种元素&#xff08;比如类、方法、结构、枚举、组件等&#xff09;的行为信息的声明性标签&#xff0c;这个标签可以有多个。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号&am…

java 技能鉴定_JAVA试题-技能鉴定

一、单选题1.以下创建了几个对象( B)String A,B,CA"a";B"b":AAB;StringBuffer Dnew StringBuffer("abc");DD.append("567");A.6B.4C.3D.52.关于以下程序段&#xff0c;正确的说法是( C )1&#xff0e;String s1“a”“b”;2&#xff0…

ADD_SHORTCUT_ACTION

String ADD_SHORTCUT_ACTION 动作&#xff1a;在系统中添加一个快捷方式。. “android.intent.action.ADD_SHORTCUT”   String ALL_APPS_ACTION 动作&#xff1a;列举所有可用的应用。   输入&#xff1a;无。 “android.intent.action.ALL_APPS”   String ALTERNATIVE…

python3中朴素贝叶斯_贝叶斯统计:Python中从零开始的都会都市

python3中朴素贝叶斯你在这里 (You are here) If you’re reading this, odds are: (1) you’re interested in bayesian statistics but (2) you have no idea how Markov Chain Monte Carlo (MCMC) sampling methods work, and (3) you realize that all but the simplest, t…

java映射的概念_Java 反射 概念理解

文章来源:http://hollischuang.gitee.io/tobetopjavaer/#/basics/java-basic/reflection反射反射机制指的是程序在运行时能够获取自身的信息。在java中&#xff0c;只要给定类的名字&#xff0c;那么就可以通过反射机制来获得类的所有属性和方法。反射有什么作用在运行时判断任…

【转载】移动端布局概念总结

布局准备工作及布局思想及概念: 一个显示器&#xff08;pc端显示器 及 手机屏显示器&#xff09;&#xff0c;既有物理像素&#xff0c;又有独立像素&#xff08;独立像素也叫作css像素&#xff0c;用于前端人员使用&#xff09;&#xff1b; -->重要 首先确定设计稿的尺寸…

深入浅出:HTTP/2

上篇文章深入浅出&#xff1a;5G和HTTP里给自己挖了一根深坑&#xff0c;说是要写一篇关于HTTP/2的文章&#xff0c;今天来还账了。 本文分为以下几个部分&#xff1a; HTTP/2的背景HTTP/2的特点HTTP/2的协议分析HTTP/2的支持 HTTP/2简介 HTTP/2主要是为了解决现HTTP 1.1性能不…

画了个Android

画了个Android 今晚瞎折腾&#xff0c;闲着没事画了个机器人——android&#xff0c;浪费了一个晚上的时间。画这丫还真不容易&#xff0c;为那些坐标&#xff0c;差点砸了键盘&#xff0c;好在最后画出个有模有样的&#xff0c;心稍安。 下面来看看画这么个机器人需要些什么东…

数据治理 主数据 元数据_我们对数据治理的误解

数据治理 主数据 元数据Data governance is top of mind for many of my customers, particularly in light of GDPR, CCPA, COVID-19, and any number of other acronyms that speak to the increasing importance of data management when it comes to protecting user data.…

mysql 选择前4个_mysql从4个表中选择

不要认为GROUP BY是必需的 . 虽然如果一个孩子有2个父记录&#xff0c;你可能想用它来将2个父母分组到一行 - 但不确定这是否是你的要求 . 因为如果一个孩子有2个父母&#xff0c;那么将为该孩子返回的父母是未定义的 .假设所有孩子都有父母&#xff0c;所有父母都会有姓&#…

提高机器学习质量的想法_如何提高机器学习的数据质量?

提高机器学习质量的想法The ultimate goal of every data scientist or Machine Learning evangelist is to create a better model with higher predictive accuracy. However, in the pursuit of fine-tuning hyperparameters or improving modeling algorithms, data might …

mysql 集群实践_MySQL Cluster集群探索与实践

MySQL集群是一种在无共享架构(SNA&#xff0c;Share Nothing Architecture)系统里应用内存数据库集群的技术。这种无共享的架构可以使得系统使用低廉的硬件获取高的可扩展性。MySQL集群是一种分布式设计&#xff0c;目标是要达到没有任何单点故障点。因此&#xff0c;任何组成部…

Python基础:搭建开发环境(1)

1.Python语言简介 2.Python环境 Python环境产品存在多个。 2.1 CPython CPython是Python官方提供的。一般情况下提到的Python就是指CPython&#xff0c;CPython是基于C语言编写的。 CPython实现的解释器将源代码编译为字节码&#xff08;ByteCode&#xff09;&#xff0c;再由虚…

python数据结构之队列(一)

队列概念队列&#xff08;queue&#xff09;是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。队列是一种先进先出的&#xff08;First In First Out&#xff09;的线性表&#xff0c;简称FIFO。允许插入的一端为队尾&#xff0c;允许删除的一端为队头。…

Android实现图片放大缩小

Android实现图片放大缩小 package com.min.Test_Gallery; import Android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.os.Bun…

matlab散点图折线图_什么是散点图以及何时使用

matlab散点图折线图When you were learning algebra back in high school, you might not have realized that one day you would need to create a scatter plot to demonstrate real-world results.当您在高中学习代数时&#xff0c;您可能没有意识到有一天需要创建一个散点图…

java判断题_【Java判断题】请大神们进来看下、这些判断题你都知道多少~

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼、判断改错题(每题2分&#xff0c;共20分)(正确的打√&#xff0c;错误的打并说明原因)1、 Java系统包提供了很多预定义类,我们可以直接引用它们而不必从头开始编写程序。 ( )2、 程序可以用字符‘*’替代一个TextField中的每个字…

PoPo数据可视化第8期

PoPo数据可视化 聚焦于Web数据可视化与可视化交互领域&#xff0c;发现可视化领域有意思的内容。不想错过可视化领域的精彩内容, 就快快关注我们吧 :) 微信订阅号&#xff1a;popodv_com谷歌决定关闭云可视化服务 Fusion Tables谷歌宣布即将关闭其 Fusion Tables 云服务&#x…