【并发编程】 synchronized的普通方法,静态方法,锁对象,锁升级过程,可重入锁,非公平锁

目录

1.普通方法

2.静态方法

3.锁对象

4.锁升级过程

5.可重入的锁

6.不公平锁

非公平锁的 lock 方法:


1.普通方法


将synchronized修饰在普通同步方法,那么该锁的作用域是在当前实例对象范围内,也就是说对于 SyncDemosd=newSyncDemo();这一个实例对象sd来说,多个线程访问access方法会有锁的限制。如果access已经有线程持有了锁,那这个线程会独占锁,直到锁释放完毕之前,其他线程都会被阻塞

public SyncDemo{Object lock =new Object();//形式1public synchronized void access(){//}//形式2,作用域等同于形式1public void access1(){synchronized(lock){//}}//形式3,作用域等同于前面两种public void access2(){synchronized(this){//}}
}


2.静态方法


修饰静态同步方法或者静态对象、类,那么这个锁的作用范围是类级别。举个简单的例子,

SyncDemo sd=SyncDemo();
SyncDemo sd2=new SyncDemo();} 


两个不同的实例sd和sd2, 如果sd这个实例访问access方法并且成功持有了锁,那么sd2这个对象如果同样来访问access方法,那么它必须要等待sd这个对象的锁释放以后,sd2这个对象的线程才能访问该方法,这就是类锁;也就是说类锁就相当于全局锁的概念,作用范围是类级别。

这里抛一个小问题,大家看看能不能回答,如果不能也没关系,后面会讲解;问题是如果sd先访问access获得了锁,sd2对象的线程再访问access1方法,那么它会被阻塞吗?

public SyncDemo{static Object lock=new Object();//形式1public synchronized static void access(){//}//形式2等同于形式1public void access1(){synchronized(lock){//}}//形式3等同于前面两种public void access2(){synchronzied(SyncDemo.class){//}}
}


3.锁对象


普通同步方法,锁是当前实例对象。比如:

public synchronized void doLongTimeTaskC() {}


4.锁升级过程


无锁——》偏向锁——》轻量级锁——》重量级锁——》GC锁

5.可重入的锁


可重入的含义:指的是同一个线程获得锁之后,再不释放锁的情况下,可以直接再次获取到该锁

@Slf4j
public class SynReentrantDemo {public static void main(String[] args) {Runnable sellTicket = new Runnable() {@Overridepublic void run() {synchronized (this) {String name = Thread.currentThread().getName();log.info("我是run,抢到锁的是{}", name);test01();} //正常来说走出临界区(这个括号)才会释放锁,但是再没走出之前,又进入test01,//而test01需要和本方法一样的锁//如果不可重入的话,就将出现死锁了-->即test01方法等着释放锁,而run方法又不会释放锁//因此synchronized只有可以在不释放run方法的锁的情况下,又再次获得该锁才不会有问题}public void test01() {synchronized (this) {String name = Thread.currentThread().getName();log.info("我是test01,抢到锁的是{}", name);}}};new Thread(sellTicket).start();new Thread(sellTicket).start();}
}


首先应该知道synchronized锁的并不是同步代码块,而是锁对象关联的一个monitor对象(在java中每一个对象都会关联一个monitor对象),而这个对象里有一个变量叫recursions — 中文是递归的意思(我想大概是因为递归的时候发生可重入的几率应该是最大的,所以才用这个当变量名的吧),其实可以将它简单理解为一个计数器。

以上面的栗子为例:

(1)当线程1抢到run方法的执行权即抢到锁时,这个recursions的值就变为了1;
(2)线程1接着运行并进入test01方法后,发现还是线程1且还是要this这把锁,就将recursions的值再+1;
(3)当线程1,执行完test01方法时,recursions的值又-1
(4)执行完run方法时recursions的值又-1,就变为了0,也就是表示线程1已经释放了this锁。
(5)之后其他线程就可以继续抢this锁了。
 

6.不公平锁


非公平锁的 lock 方法:

static final class NonfairSync extends Sync {final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}// AbstractQueuedSynchronizer.acquire(int arg)public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}final boolean nonfairTryAcquire(int acquires) {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) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;
}


公平锁和非公平锁只有两处不同:

非公平锁在调用 lock 后,首先就会调用 CAS 进行一次抢锁,如果这个时候恰巧锁没有被占用,那么直接就获取到锁返回了。
非公平锁在 CAS 失败后,和公平锁一样都会进入到 tryAcquire 方法,在 tryAcquire 方法中,如果发现锁这个时候被释放了(state == 0),非公平锁会直接 CAS 抢锁,但是公平锁会判断等待队列是否有线程处于等待状态,如果有则不去抢锁,乖乖排到后面。
公平锁和非公平锁就这两点区别,如果这两次 CAS 都不成功,那么后面非公平锁和公平锁是一样的,都要进入到阻塞队列等待唤醒。

相对来说,非公平锁会有更好的性能,因为它的吞吐量比较大。当然,非公平锁让获取锁的时间变得更加不确定,可能会导致在阻塞队列中的线程长期处于饥饿状态。
 

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

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

相关文章

ORBSLAM3安装

1. 依赖 在该目录下打开终端,安装下面所有依赖。 1. 1 编译软件 sudo apt-get install gccsudo apt-get install g++sudo apt-get install build-essentialsudo apt-get install cmakesudo apt-get install openssl sudo apt-get install libssl-dev1. 2 Pangolin git cl…

蓝桥杯备战——5.动态数码管扫描

1.分析原理图 经查阅说明书得知数码管为共阳极&#xff0c;共阳端口接到了U8,而段码接到了U7。 如果需要选中U8,我们只需要将P250;P261;P271; 如果需要选中U7,我们只需要将P251;P261;P271; 2.代码示例 void Delay1ms() //12.000MHz {unsigned char data i, j;i 12;j 169;…

java以SSL方式连ES

先做准备工作&#xff0c;浏览器方式访问 ES7.X url https://127.0.0.1:8027 弹出用户名和密码 输入后在浏览器得到 { “name” : “DTCNPEMS04”, “cluster_name” : “cnp-es-cluster”, “cluster_uuid” : “wb0So_FqQBOKqtXnsqofTg”, “version” : { “number” : “7.…

java web 校园健康管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web校园健康管理系统是一套完善的java web信息管理系统 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…

第一篇【传奇开心果短博文系列】Python的库OpenCV技术点案例示例:cv2常用功能和方法

传奇开心果短博文系列 短博文系列目录Python的库OpenCV技术点案例示例系列 短博文目录一、前言二、常用功能和方法示例三、归纳总结 短博文系列目录 Python的库OpenCV技术点案例示例系列 短博文目录 一、前言 cv2是Python中常用的第三方库&#xff0c;也称为OpenCV库&#…

视频监控方案设计:EasyCVR视频智能监管系统方案技术特点与应用

随着科技的发展&#xff0c;视频监控平台在各个领域的应用越来越广泛。然而&#xff0c;当前的视频监控平台仍存在一些问题&#xff0c;如视频质量不高、监控范围有限、智能化程度不够等。这些问题不仅影响了监控效果&#xff0c;也制约了视频监控平台的发展。 为了解决这些问…

学生护眼灯哪个品牌好?最好的学生护眼灯品牌排行

说到台灯&#xff0c;相信大家都不陌生&#xff0c;特别是对于家中有学生的家长们而言&#xff0c;一款优秀的护眼台灯已经成为居家必备的工具之一。然而&#xff0c;随着各种护眼台灯层出不穷&#xff0c;价格从几百到上千不等&#xff0c;人们对于这一领域的产品是否物有所值…

【Linux】-网络概念

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

[pytorch入门] 2. tensorboard

tensorboard简介 TensorBoard 是一组用于数据可视化的工具。它包含在流行的开源机器学习库 Tensorflow 中.但是也可以独立安装&#xff0c;服务Pytorch等其他的框架 可以常常用来观察训练过程中每一阶段如何输出的 安装pip install tensorboard启动tensorboard --logdir<d…

帆软数据决策系统——用户名或密码错误解决方案

今天在公司调试本地大屏效果效果&#xff0c;死活登录不上数据决策系统。 附上截图&#xff1a; 解决方案&#xff1a; 找到本地FineReport设计器的安装路径&#xff0c;例如&#xff1a;D:\commonsoftware\FineReport_11.0\setup\FineReport_11.0\webapps\webroot\WEB-INF\em…

【医学图像隐私保护】PLAN方法:解决 GAN 生成医学图像 Latent 空间中的隐私保护

PLAN方法&#xff1a;解决 GAN 生成医学图像 Latent 空间中的隐私保护方法 PLAN 原理StyleGAN 生成视网膜图k-SALSA 生成视网膜图PLAN方法 生成视网膜图 总结 PLAN 原理 论文&#xff1a;https://arxiv.org/abs/2307.02984 代码&#xff1a;https://github.com/perceivelab/P…

笔记--写代码好习惯

原文&#xff1a;写代码有这16个好习惯&#xff0c;可以减少80%非业务的bug

ai数字人透明屏在金融行业的应用

AI数字人透明屏在金融行业的应用主要体现在以下几个方面&#xff1a; 客户服务&#xff1a;AI数字人透明屏可以作为客户服务的重要工具&#xff0c;为客户提供24小时全天候的服务。通过自然语言处理和语音识别技术&#xff0c;AI数字人能够理解和回答客户的问题&#xff0c;提…

计算机网络 第6章(应用层)

系列文章目录 计算机网络 第1章&#xff08;概述&#xff09; 计算机网络 第2章&#xff08;物理层&#xff09; 计算机网络 第3章&#xff08;数据链路层&#xff09; 计算机网络 第4章&#xff08;网络层&#xff09; 计算机网络 第5章&#xff08;运输层&#xff09; 计算机…

[docker] Docker的数据卷、数据卷容器,容器互联

一、数据卷&#xff08;容器与宿主机之间数据共享&#xff09; 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数据不会影响镜像&#xff0c;从而实现数据在宿主机与容…

【Linux】 开始使用 gcc 吧!!!

Linux 1 认识gcc2 背景知识3 gcc 怎样完成 &#xff1f;3.1 预处理预处理^条件编译 3.2 编译3.3 汇编3.4 链接 4 函数库5 gcc 基本选项Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下一篇文章见&#xff01;&#xff01;&#xff01; 1 认识gcc 我们在windows环…

windows和linux下SHA1,MD5,SHA256校验办法

今天更新android studio到Android Studio Hedgehog | 2023.1.1时&#xff0c;发现提示本机安装的git版本太老&#xff0c;于是从git官网下载最新的git。 git下载地址&#xff1a; https://git-scm.com/ 从官网点击下载最新windows版本会跳转到github仓库来下载发布的git&…

unity 装饰器模式(实例详解)

文章目录 简介1. **组件装饰器&#xff08;Component Decorators&#xff09;**:2. **游戏对象特效装饰器&#xff08;GameObject Effects Decorator&#xff09;**:3. **输入处理装饰器&#xff08;Input Handling Decorators&#xff09;**:4. **性能优化装饰器&#xff08;P…

JWT登录

JWT JSON Web Token&#xff08;JSON Web令牌&#xff09; 是一个开放标准(rfc7519)&#xff0c;它定义了一种紧凑的、自包含的方式&#xff0c;用于在各方之间以JSON对象安全地传输信息。此信息可以验证和信任&#xff0c;因为它是数字签名的。jwt可以使用秘密〈使用HNAC算法…

行业报告 | 人形机器人的产业研报分析

原创 | 文 BFT机器人 对于人形机器人&#xff0c;相信大家都不陌生。随着科技的飞速发展&#xff0c;人形机器人已经从科幻小说和电影走进了我们的现实生活。 近年来&#xff0c;机器人技术创新不断&#xff0c;人形机器人在教育、医疗、工业生产等各个领域都有广泛的应用前景…