当前位置:网站首页>synchronized真的很重么?
synchronized真的很重么?
2022-04-21 09:25:00 【@zzyang】
synchronized 是java中常见的保证多线程访问共享资源时的安全的一个关键字。很多人在讲到synchronized 时都说synchronized 是一把重量级的锁,那么synchronized 真的很重么?
synchronized 在jdk 1.6以前(不包括1.6)的确是一把很重的锁,每次使用锁的时候都是直接向操作系统请求的,所以效率低,且占资源,但是在jdk1.6以后,jvm对synchronized 进行了优化,加入了锁升级的功能,使得synchronized 在一些情况下并不是一把重量级的锁,而是一个很轻的一把锁。
本文就来探讨一下,jdk对synchronized 优化,包括锁升级、锁粗化、锁消除。
一、锁升级
锁升级其实是指,随着多线程并发加锁的程度提高而相应的对锁的状态的升级,可以分为:偏向锁、轻量级锁、自旋锁、重量级锁;
偏向锁
偏向锁不是一把锁,而是代表了当前synchronized 锁状态。偏向锁是一把很轻的锁,当只有一个来线程加锁的时候,此时synchronized 锁就会变成偏向锁,偏向锁代表这个锁偏向这个线程,就是说当这个线程再次来加锁的时候,不需要再向操作系统申请资源,而是很快就能获取到锁,减少了申请锁的开销。
为什么需要偏向锁。因为在大多数情况下,多线程竞争同一把锁的情况是很少的,那么在没有多线程并发竞争的情况下,其实没必要再去向系统申请重量级锁了,我就用目前这把偏向锁就够了,因为申请重量级会耗费比较大的资源。
轻量级锁
当随着更多线程来加锁的时候,偏向锁就会无法满足使用的条件了,因为偏向锁认为加锁的线程只有一个。
那么多线程加锁有可能会出现这种情况。当会有两个及以上的线程来加锁,但是没有出现同时来竞争锁的情况,也就是说虽然有多个线程来加锁,可能会出现A线程加完锁之后释放了锁,此时B来加锁,发现并没有线程持有锁,也就说没有线程跟B来竞争,也就相当于多线程来交替加锁的情况。
当出现这种情况的时候,偏向锁就会升级为轻量级锁。轻量级锁就是指虽然可能会出现多线程来加锁的情况,但是并不存在锁竞争的情况,并不会存在锁冲突。
自旋锁
上面说到随着加锁的线程变多,出现了多线程交替加锁的情况,偏向锁会升级为轻量级锁,但是随着并发加锁的线程越来越多,出现了多个线程同时来加锁的情况,也就不是交替加锁,那么此时轻量级锁已经不适合使用了,但是jvm为了防止锁直接升级为重量级锁(因为挂起线程和恢复线程的操作都需要转入到内核态中完成,这些操作给系统的并发性能带来很大的压力),加入了线程自旋的机制。所谓的自旋就是虽然加锁失败了,但是有可能出现其他线程很快就释放锁的情况,那么就尝试不断的自旋来尝试加锁,而不是直接将锁升级为重量级锁。
自旋锁的好处就是用来减少操作系统的压力。
重量级锁
但是随着加锁的线程不断增多,自旋了一定的时间或者次数也没有成功加锁,那么锁就会升级为重量级锁,因为自旋会消耗cpu,一直这么自旋也不是很好的选择,所以就会升级为重量级锁。升级为重量级锁之后,所有来加锁的线程加锁失败之后,就会加入等待的队列中,等待别的线程释放锁之后再进行锁的竞争。
通过以上的分析,我们也看出了,synchronized 在最开始的时候并不是上来就是一把重量级的锁,而是随着多线程并发竞争锁的激烈程度的提高来不断的升级,慢慢变成重量级锁,在整个升级的过程会经历偏向锁、轻量级锁、自旋锁、重量级锁的过程。
二、锁消除
先来看一段代
public class SynchronizedDemo {
public static void main(String[] args) {
Object monitor = new Object();
synchronized (monitor){
System.out.println("加锁成功....");
}
}
}
通过上面代码我们可以看出,synchronized 的锁对象其实是方法的一个局部变量,那么对于这种情况,不会出现多线程竞争同一把Object 对象锁的情况,那么在运行的时候就会忽略这个synchronized 加锁的过程。
说的官方一点就是指虚拟机即时编译器在运行时,对一些代码上要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除。
三、锁粗化
public class SynchronizedDemo {
private static final Object MONITOR = new Object();
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
synchronized (MONITOR) {
System.out.println("加锁成功....");
}
}
}
}
通过这段代码的分析,可以看出,循环内部每次都对同一个对象进行加锁和解锁,对于这种一串零碎的操作都对同一个对象加锁情况,虚拟机将会把加锁同步的范围扩展 (粗化)到整个操作序列的外部。以上述代码为例,也就是扩展到把for循环这个操作加锁,这样只需要加锁一次就可以了。
总结
所以,通过本篇文章可以看出,jdk对synchronized 其实进行了一系列的优化来尽可能减少加锁时对于性能的消耗,包括锁升级、锁消除、锁粗化。希望通过本篇文章可以让你对synchronized 底层又有一个全新的认识。
如果觉得这篇文章对你有所帮助,还请帮忙点赞、在看、转发一下,码字不易,非常感谢!
如果你想联系我,欢迎关注我的个人的微信公众号三友的java日记,每天都会发布技术性的文章,同时也可以添加我的微信ZZYNKXJH与我取得联系。期待与你一起进步。
版权声明
本文为[@zzyang]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_45630885/article/details/124219092
边栏推荐
- Opencv -- separate color channel, image contrast, brightness adjustment, discrete Fourier transform (10)
- Penetration test - get the system fofa keyword to brush the hole
- Open3d读写ply点云文件
- Open3d reads and writes PCD point cloud files
- Buuctf [geek challenge 2019] havefun
- ShardingSphere简介
- 数据库有张表,其中一个字段存的是json数据,我需要在这张表有更新的时候,解析这个字符串,然后把解析的json数据更新到另外一个表,有什么好的建议?
- PageRank case Airport
- [MySQL] Based on linux-centos7 9 detailed installation tutorial
- 1146: 吃糖果
猜你喜欢

2022 Shandong Province safety officer C certificate examination questions and simulation examination
![[paper reading] [iccv 2021] rpnet: learning inner group relations on point clouds](/img/37/0a1eb88aa20a6a3c4586137066e28a.png)
[paper reading] [iccv 2021] rpnet: learning inner group relations on point clouds

【栈和队列】C语言简单应用 ⌊栈和队列互相实现,循环队列⌉

postman测试Excel文件导入导出功能
Serviceworker cache and HTTP cache

计算器(力扣)

Handler asynchronous message passing mechanism (I) common basic usage of handler

Drafting and Revision: Laplacian Pyramid Network for Fast High-Quality Artistic Style Transfer--T Li

CC00026.CloudJenkins—————————————

Notes of the most complete grain mall in the whole network_ 02. Introduction to the overall effect of the project (2022-04-02)
随机推荐
Getting started with object detection FAQs (deep learning / image classification)
2017我也开始真正写CSDN博客(新浪网易转战CSDN)
2022 tea artist (primary) examination questions and online simulation examination
Open3d读写ply点云文件
Drafting and Revision: Laplacian Pyramid Network for Fast High-Quality Artistic Style Transfer--T Li
2022 chemical automation control instrument examination exercises and simulation examination
Surfaceview high performance rendering (IV) code practice - drawing multiple pictures
1161: 字符串长度(指针专题)
ShardingSphere简介
纯c语言链表实现学生信息管理系统.(你学会了吗?)
1169: 大整数(指针专题)
About shardingsphere
CC00026.CloudJenkins—————————————
CC00000.CloudJenkins—————————————
1149: 组合三位数之二
使用LamdbaUpdateWrapper的setSql作用及风险
Redisson introduction and integration
全网最全谷粒商城笔记_02、简介项目整体效果展示(2022-04-02)
[MySQL] Based on linux-centos7 9 detailed installation tutorial
SQL is a general fuzzy query statement. Query table T and seq of table t2 are conditions. How can fuzzy query match multiple characters of SEQ of table t2?