Java多线程(十)

news2024/12/23 5:40:26

目录

一、synchronized基本特点

二、synchronized加锁工作过程

2.1 无锁

2.2 偏向锁

2.3 轻量级锁

2.4 重量级锁

三、synchronized其他优化操作

3.1 锁消除

3.2 锁粗化


一、synchronized基本特点

  1. 开始是乐观锁,如果锁冲突频繁就会转换成悲观锁
  2. 开始是轻量级锁,如果锁被持有的时间变长就会升级成重量级锁
  3. 轻量级锁是通过自旋锁来实现的,重量级锁基于系统的互斥锁来实现的
  4. 是不公平锁(这里的不公平指的是不按照顺序执行线程,谁抢到算谁的)
  5. 是可重入锁(内部会通过计数器来记录加锁次数)
  6. 不是读写锁

二、synchronized加锁工作过程

由于synchronized具有多种特性,所以在加锁的过程中也是有不同的状态。Jvm将synchronized锁分为:无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁 这4种状态,会根据不同的场景依次进行升级。

2.1 无锁

无锁的解释很简单,线程可能加锁了,但是该线程还能没有被执行,此时synchronized就还处于无锁的状态。也就是说synchronized不会一开始就加锁,这也是效率提升的原因。

2.2 偏向锁

偏向锁不是真的加锁,只是对这个这个锁进行一个“偏向锁标记”,记录当前锁属于哪个线程。当后续有线程进行锁竞争的时候再升级为轻量级锁。

这里的这种做法就类似于单例模式中的懒汉模式,能不加锁就不加锁,尽量避免不必要的开销。但是还是会做好标记,在遇到锁竞争的时候方便加锁。

2.3 轻量级锁

随着其他线程进入竞争,偏向锁的状态解除,进入轻量级锁状态(自适应的自旋锁)。其他线程可能没有直接放弃,而是持续访问查看上个线程是否释放锁,如果释放就能第一时间拿到锁。但是这种情况下也有缺点,如果是上个线程持有的时间比较久,那么这样就会持续的消耗cpu资源。

2.4 重量级锁

如果锁竞争进一步激烈,自旋不能快速的获取到锁,那么synchronized就会膨胀为重量级锁。这里的重量级锁是指内核提供的mutex。

  • 执行加锁操作, 先进入内核态.
  • 在内核态判定当前锁是否已经被占用
  • 如果该锁没有占用, 则加锁成功, 并切换回用户态.
  • 如果该锁被占用, 则加锁失败. 此时线程进入锁的等待队列, 挂起. 等待被操作系统唤醒.
  • 经历了一系列的沧海桑田, 这个锁被其他线程释放了, 操作系统也想起了这个挂起的线程, 于是唤醒这个线程, 尝试重新获取锁.

三、synchronized其他优化操作

3.1 锁消除

这里的锁消除指的是当代码中加了synchronized锁但是并没有多线程,这里的编译器+Jvm就会直接将锁进行消除。但是并不是所有的场景编译器+Jvm都会进行这种优化,所以在编写代码的过程中还是需要自己编写的规范,不要过度依靠外物。

3.2 锁粗化

首先要了解一下这里的“粗”是指的什么,这里“粗”指的是synchronized中执行代码的多少,如果一段代码中多次出现加锁解锁,编译器+Jvm就会自动执行锁的粗化。

举个例子理解锁粗化:

滑稽老哥当了领导, 给下属交代工作任务:
方式一:
打电话, 交代任务1, 挂电话.
打电话, 交代任务2, 挂电话.
打电话, 交代任务3, 挂电话.
方式二:
打电话, 交代任务1, 任务2, 任务3, 挂电话.
显然, 方式二是更高效的方案.

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

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

相关文章

python小白之matplotlib使用实战项目:随机漫步

文章目录 随机漫步1.1 创建RandomWalk类1.2 选择方向1.3 绘制随机漫步图1.4 模拟多次随机漫步1.5 设置随机漫步图样式1.5.1 给点着色1.5.2 重新绘制起点和终点1.5.3 隐藏坐标轴1.5.4 增加点数1.5.5 调整图片尺寸以适应屏幕 附录(项目代码)random_walk.py…

Linux 外部命令 - cat

Linux 外部命令 cat 英文帮助 NAME cat - concatenate files and print on the standard output SYNOPSIS cat [OPTION]... [FILE]... DESCRIPTION Concatenate FILE(s) to standard output. With no FILE, or when FILE is -, read standard input.…

ChatAI的几十种高级用法,可能是比较全的了(文末送书)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

【Kafka】1.Kafka简介及安装

目 录 1. Kafka的简介1.1 使用场景1.2 基本概念 2. Kafka的安装2.1 下载Kafka的压缩包2.2 解压Kafka的压缩包2.3 启动Kafka服务 1. Kafka的简介 Kafka 是一个分布式、支持分区(partition)、多副本(replica)、基于 zookeeper 协调…

消息中间件 —— 初识Kafka

文章目录 1、Kafka简介1.1、消息队列1.1.1、为什么要有消息队列?1.1.2、消息队列1.1.3、消息队列的分类1.1.4、p2p 和 发布订阅MQ的比较1.1.5、消息系统的使用场景1.1.6、常见的消息系统 1.2、Kafka简介1.2.1、简介1.2.2、设计目标1.2.3、kafka核心的概念 2、Kafka的…

Java pb3中 int类型的字段值0怎么判断是未设置值还是设置了值0

Java pb3中 int类型的字段值0怎么判断是未设置值还是设置了值0 1. 效果图2. 源码参考 Java pb3对 各种类型的默认值进行序列化时省略了。如int类型的字段为0或者null都会省略,但反序列化都可以序列化为0. proto3, required 和 optional 已在新语法中删除…

闲鱼卖货:新手容易踩坑的7个地方。赶紧看看有没有中招?

科思创业汇 大家好,这里是科思创业汇,一个轻资产创业孵化平台。赚钱的方式有很多种,我希望在科思创业汇能够给你带来最快乐的那一种! 这是我以前的一个学生收到的第一个非法通知。他告诉我,他当时很害怕,…

在 SHELL 脚本中调用另一个 SHELL 脚本(报错: go: not found)

文章目录 在 SHELL 脚本中调用另一个 SHELL 脚本(报错: go: not found)在 SHELL 脚本中调用另一个 SHELL 脚本一个脚本sudo调另外一个脚本,报错(报错: go: not found) 在 SHELL 脚本中调用另一个…

LNMP简易搭建

目录 前言 一、拓扑图 二、NGINX配置 三、配置MySQL 四、配置php环境 五、部署应用 总结 前言 LNMP平台指的是将Linux、Nginx、MySQL和PHP(或者其他的编程语言,如Python、Perl等)集成在一起的一种Web服务器环境。它是一种常用的开发和部署网…

Linux使用gdb调试多文件的C程序

【例】通过vi创建两个.c文件main.c和add.c: 一步编译main.c和add.c文件,并加入调试信息: 1. 在被调函数中加断点时,在执行主函数时,会自动进入被调函数 (1)进入gdb,跟踪main程序&am…

python——案例17:判断某年是否是闰年

案例17:判断某年是否是闰年 判断依据:闰年就是能被400整除,或者能被4整除的年份numint(input(输入年份:))if num%1000: if num%4000: #整百年份的判断print("%s年是闰年"%num) #…

智能优化算法:登山队优化算法-附代码

智能优化算法:登山队优化算法 文章目录 智能优化算法:登山队优化算法1.登山队优化算法1.1 初始化1.2 协作登山1.3灾害威胁1.4协调防御1.5队员更新 2.实验结果3.参考文献4.Matlab5.python 摘要:MTBO 算法是 Faridmehr 等人于 2023 年受登山队员…

【智力悬疑题】——【“找凶手”解法】

“找凶手”题目解法 “案件题目”💻 某地发生了一起凶杀案,警察通过排查确定杀人凶手必为4个嫌疑犯中的一个。以下为4个嫌疑犯的供词: A说:不是我。 B说:是C。 C说:是D。 D说:C在胡说。 已知3个…

vue3+vite在main.ts文件中引入./App.vue报错(./App.vue不是模块)

问题 如下图: 方法一 下载TypeScript Vue Plugin (Volar)插件就不报红了,看它的描述应该就是ts文件可以识别vue文件。 方法二 在src文件夹下添加env.d.ts文件,添加以下代码: declare module *.vue {import type { DefineC…

Android系统-进程-Binder2-Java层

引言: 对于Android系统,一般是从java层到native层,再到kernel驱动层,形成一个完整的软件架构。Android系统中的Binder IPC通信机制的整体架构,从java层到底层驱动层是怎么样的一个架构和原理的呢? 概念与…

详解单链表

💕十载寒窗无人问,一举成名天下知💕 作者:Mylvzi 文章主要内容:程序环境和预处理 引言: 我们之前已经学习过顺序表,顺序表是一种线性的存储结构,它在内存中是连续存放的&#xff1…

《Java-SE-第三十五章》之方法引用

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页:KC老衲爱尼姑的博客主页 博主的github,平常所写代码皆在于此 共勉:talk is cheap, show me the code 作者是爪哇岛的新手,水平很有限&…

微服务实战项目-学成在线-项目部署

微服务实战项目-学成在线-项目部署 1 什么是DevOps 一个软件的生命周期包括:需求分析阶、设计、开发、测试、上线、维护、升级、废弃。 通过示例说明如下: 1、产品人员进行需求分析 2、设计人员进行软件架构设计和模块设计。 3、每个模块的开发人员…

Vue3实现图片懒加载及自定义懒加载指令

Vue3实现图片懒加载及自定义懒加载指令 前言1.使用vue-lazyload/vue3-lazyload插件2.自定义v-lazy懒加载指令2.1 使用VueUse工具集2.2 使用IntersectionObserver 前言 图片懒加载是一种常见性能优化的方式,它只去加载可视区域图片,而不是在网页加载完毕…

直线电机模组在3C电子行业中的重要应用

直线模组的种类有很多,是自动化行业中必不可少的传动元件,其中丝杆模组和同步带模组的应用率比较高,但随着自动化领域的迅速发展,高精密直线电机模组也得到了广泛的应用,尤其是在电子行业中的应用。 3C电子产品在我们的…