Java中的悲观锁机制----synchronized 关键字原理

上篇铺垫:Java中的锁机制?(体系梳理篇)-CSDN博客

一、sychronized的介绍

sychronized是Java原生的一个同步锁机制,可以保证在多线程并发的情况下,仅允许一个线程执行加锁的方法和代码块,保证了线程安全。

在Java1.5之前,sychronized关键字实现的同步锁,底层是一种悲观锁的理念,在1.6版本后,Java对该关键字进行了优化,使得该锁在某些情况下呈现轻量锁的作用(这个后面介绍,先有个印象)

二、sychronized的作用

  • 原子性:保证各个线程间的互斥。
  • 可见性:保证共享变量的可见性,就是在加锁的时候仅允许持有锁的线程修改变量,在修改结束后,该变量的值会同步到内存当中,保证其他变量可以访问这个变量的修改。
  • 有序性:有效解决重排序问题,即 “一个unlock操作先行发生(happen-before)于后面对同一个锁的lock操作”;

对于可见性,可能很多人有疑问,volatile关键字也是保证共享变量的可见性,它和sychronized有什么区别?

volatile关键字保证了你对当前变量的修改会直接同步到内存中,而sychronized关键字它是先加锁然后修改值,释放锁之后才会把值同步到内存中,sychronized是有一个加锁的过程,保证了原子性,而volatile关键字并没有加锁,因此它并不具备原子性。

那么很多人可能又想问volatile关键字如何保证线程并发问题?

很简单,通过CAS来保证在多线程并发情况下,仅有一个线程修改volatile修饰的变量。详情请看Java中的锁机制?(体系梳理篇)-CSDN博客

三、Java1.6之后对sychronized关键字的优化了什么?

在1.5版本之前,sychronized关键字底层是一个互斥锁,是一个重量级锁,怎么理解呢?只要我对当前代码块加锁,那么无论我持锁线程是读取值还是修改值,其他的线程都必须等待我当前线程释放锁,然而在很多情况下,大部分都是读操作,并不需要如此重量级的线程管控。

因此在Java1.6版本之后,Java对sychronized关键字进行了优化。在Java1.6中,sychronized并不会直接对锁进行重量级锁的实现,而是会根据实际情况一步步将锁升级为重量级锁。我们先了解一下锁的几种状态:

  • 无锁

当前线程第一次访问加锁代码块,此时代码块还未加锁,成为无锁。如何辨别是第一次访问呢?在加锁的对象头中又有一个threadid字段,用于表示当前代码块是否被加锁。

  • 偏向锁

当前线程第二次访问加锁代码块,此时代码块已经被当前线程加了一次锁,在读取threadid字段后,知道是当前线程在持有锁,锁升级为偏向锁。此时会对当前线程直接放行,不需要重复申请锁,通过这种机制,实现了可重入锁,也就是当前线程可以重复获取当前锁。

  • 轻量锁

轻量级锁是由偏向锁升级而来,当存在第二个线程申请同一个锁对象时,偏向锁就会立即升级为轻量级锁。第二个线程会通过一定的自旋循环来获取锁。

  • 重量锁

重量级锁是由轻量级锁进一步升级而来,当同一时间有多个线程竞争锁时,自旋线程过多,锁就会被升级成重量级锁,因为自旋线程过多会严重消耗cpu性能。

2.锁消除

消除锁是虚拟机另外一种锁的优化,这种优化更彻底,在JIT编译时,对运行上下文进行扫描,去除不可能存在竞争的锁。比如下面代码的method1和method2的执行效率是一样的,因为object锁是私有变量,不存在所得竞争关系。

3. 锁粗化

锁粗化是虚拟机对另一种极端情况的优化处理,通过扩大锁的范围,避免反复加锁和释放锁。比如下面method3经过锁粗化优化之后就和method4执行效率一样了。

四、sychronized的底层原理

synchronized 同步代码块的实现是通过 monitorenter 和 monitorexit 指令,其中 monitorenter 指令指向同步代码块的开始位置,monitorexit 指令则指明同步代码块的结束位置。当执行 monitorenter 指令时,线程试图获取锁也就是获取 monitor(monitor对象存在于每个Java对象的对象头中,synchronized 锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因) 的持有权。

其内部包含一个计数器,当计数器为0则可以成功获取,获取后将锁计数器设为1也就是加1。相应的在执行 monitorexit 指令后,将锁计数器设为0,表明锁被释放。如果获取对象锁失败,那当前线程就要阻塞等待,直到锁被另外一个线程释放为止。

synchronized 修饰的方法并没有 monitorenter 指令和 monitorexit 指令,取得代之的确实是 ACC_SYNCHRONIZED 标识,该标识指明了该方法是一个同步方法,JVM 通过该 ACC_SYNCHRONIZED 访问标志来辨别一个方法是否声明为同步方法,从而执行相应的同步调用。

五、sychroized为什么是非公平锁?

要讨论这个问题,我们必须明白什么是公平锁?什么是非公平锁?

  • 公平锁:公平锁是指,当锁被当前线程持有,其他线程会按照先后顺序排队,排在前面的会优先获取锁,这就称为公平锁,在Java中JUC包下的AQS就可以实现公平锁,至于原理我们下篇文章介绍AQS时展开讨论。
  • 非公平锁:由上面结论我们举反例可以知道,非公平锁就是,我不管你是否先来,谁先抢到锁谁就执行,sychronized就是一个非公平锁。

但为什么呢?其实很简单,在sychronized中有两个池的概念,一个是EntryList,一个是WaitSet,EntryList是一个单链表结构,当线程获取锁失败后,线程就会被封装称Entry对象然后加入到EntryList中。当某个持有锁线程调用wait()方法,线程就会释放锁然后加入到WaitSet中,当该线程被唤醒后会加入到EntryList中等待JVM调用。

但JVM并不会按照顺序去调用EntryList中的线程,而是随机调用,这也就导致了sychronized是一个非公平锁。

至于锁对象头的内容大家请看这篇文章:synchronized详解-CSDN博客

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

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

相关文章

深度剖析:数字经济下人工智能水平的新测算模型数据集

数据来源:企业年报时间跨度:1991-2022年数据范围:各企业数据指标: 年份 股票代码 公司名称 总词频 词频加1取对数 人工智能 计算机视觉 图像识别 知识图谱 智能教育 增强现实 智能政务 特征提…

数据分析-Pandas序列时间移动窗口化操作

数据分析-Pandas序列时间移动窗口化操作 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表…

Machine Learning ---- Feature Scaling

目录 一、What is feature scaling:: 二、Why do we need to perform feature scaling? 三、How to perform feature scaling: 1、Normalization: 2、Mean normalization: 3、Standardization (data needs to follow a normal distribution): 一、What is featur…

高效使用git流程分享

准备 假设你已经 clone 了当前仓库,并且你的终端位置已经位于仓库目录中。 查询状态 查询状态常用的命令有 git status 和 git branch。 前者用于查询更改文件情况,后者用于展示所有分支。 chatbot-system$ git status On branch develop Your bran…

Fiddler不仅可以抓包,还可以做接口测试喔

前言 Fiddler最大的优势在于抓包,我们大部分使用的功能也在抓包的功能上,Fiddler做接口测试也是非常方便的。对应没有接口测试文档的时候,可以直接抓完包后,copy请求参数,修改下就可以了。 Composer简介 点开右侧Co…

深入解析JVM加载机制

一、背景 Java代码被编译器变成生成Class字节码,但字节码仅是一个特殊的二进制文件,无法直接使用。因此,都需要放到JVM系统中执行,将Class字节码文件放入到JVM的过程,简称类加载。 二、整体流程 三、阶段逻辑分析 3…

MySQL主从数据库简单搭建

环境:准备两个linux虚拟机服务器,两台需要安装相同版本的MySQL服务,此处示例使用的是 10.6.8-MariaDB MariaDB Server 版本,确保两台服务器可以ping通,检查防火墙是否关闭,或防火墙开启但对应数据库端口需要…

到底什么时候该使用MongoDB

NoSQL是什么 NoSQL : Not Only SQL , 本质也是一种数据库的技术,相对于传统数据库技术,它不会遵循一些约束,比如 : sql 标准、 ACID 属性,表结构等。 NoSQL分类 类型应用场景典型产品Key-value存储缓存&…

考研数学|跟武忠祥,刷什么习题集效果最好?

选择听哪位老师的课程并不是硬性规定。我个人觉得,关键在于根据自己的学习需求和情况来选择合适的学习方式。比如如果听武忠祥老师的课程可能更适合你,你可以选择武忠祥老师;而如果你希望通过大量的题目练习来提高解题能力,那么选…

【Unity】Transform、Rigidbody、CharacterController移动

前言 在使用Unity开发的时候,移动是最最基础的一个需求,我来给大家简单的讲一下Unity中的几种常见的移动方法。 1.Transform移动 Transform移动就是修改物体的position ①修改位置 这里要注意:坐标分为世界坐标和本地坐标 //将物体的世界坐…

如何解决网络中IP地址发生冲突故障?

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记,未经本人许可,请勿转载,如发现本笔记内容的错误还望各位不吝赐教(笔记内容可能有误怕产生错误引导)。 1、个人IP地址冲突解决方案 首先winR,调出…

关于 闰年 的小知识,为什么这样判断闰年

闰年的规定&#xff1a; 知道了由来&#xff0c;我们就可以写程序来判断&#xff1a; #include <stdio.h> int main() {int year, leap;scanf("%d",&year);if((year%4 0 && year%100 ! 0) || year%400 0)leap 1;else leap 0;if(leap) printf(…

【Linux下qt软件安装打包附带问题: dpkg: error processing package xxxx +解决方式+自我尝试+记录】

【Linux下qt软件安装打包附带问题&#xff1a; dpkg: error processing package xxxx 解决方式自我尝试记录】 1、前言2、实验环境3、问题说明4、我的努力与查到解决的方式&#xff08;1&#xff09;补充两个文件&#xff0c;让软件正常执行&#xff08;2&#xff09;尝试修复d…

29.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-数据推测功能的算法实现

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;28.数据推测结果…

智慧公厕对于智慧城市管理的意义

近年来&#xff0c;智慧城市的概念不断被提及&#xff0c;而智慧公厕作为智慧城市管理的重要组成部分&#xff0c;其在监测、管理和养护方面发挥着重要的作用。智慧公厕不仅是城市市容提升的重要保障&#xff0c;还能提升城市环境卫生管理的质量&#xff0c;并有效助力创造清洁…

springBoot项目,无配置中心,怎么实现类似功能

实现EnvironmentPostProcessor import cn.hutool.http.HttpUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.env.YamlPropertySourceLoader; import org.springfr…

用electron将vue项目打包成.exe文件【保姆级教程】

用electron将vue项目打包成.exe文件【保姆级教程】 说明&#xff1a; vue2项目&#xff0c;使用的vue-element-admin框架&#xff0c;用electron打包成.exe文件。 1、新建一个文件夹&#xff0c;然后右键打开终端或者cd到这个目录。执行下面的命令&#xff08;最好确认一下gith…

c语言文件操作(中)

目录 1. 文件的顺序读写1.1 顺序读写函数1.2 顺序读写函数的原型和介绍 结语 1. 文件的顺序读写 1.1 顺序读写函数 函数名功能适用于fgetc字符输入函数所有输出流fputc字符输出函数所有输出流fgets文本行输入函数所有输出流fputs文本行输出函数所有输出流fscanf格式化输入函数…

AI+权重衰退

AI权重衰退 1权重衰退2代码实现 2丢弃法 1权重衰退 AI权重衰退是指在人工智能&#xff08;AI&#xff09;领域中的一种技术或方法&#xff0c;用于训练机器学习模型时对权重进行惩罚或调整&#xff0c;以避免过拟合现象的发生。 在机器学习中&#xff0c;过拟合是指模型在训练…

红队笔记7--Web机器为Linuxdocker逃逸

其实&#xff0c;不知道大家有没有想过&#xff0c;我们之前练习的都是web机器是windows的版本&#xff0c;但是其实&#xff0c;在现实生活中&#xff0c;服务器一般都是Linux的版本&#xff0c;根本不可能用到windows的版本 那么如果是Linux的话&#xff0c;我们就有很多的困…