当前位置:网站首页>Synchronized锁及其膨胀
Synchronized锁及其膨胀
2022-04-23 02:13:00 【Java知识图谱】
一、序言
在并发编程中,synchronized
锁因其使用简单,在线程间同步被广泛应用。下面对其原理及锁升级过程进行探究。
二、如何使用
1、修饰实例方法
当实例方法被synchronized修饰时,通过当前实例调用此方法的所有线程共用一把锁,不同对象调用此方法线程间互不影响。
public class A { public synchronized void func() { }}
当使用synchronized锁修饰实例方法,锁添加在当前类的实例上,有多少个实例可添加多少把锁。
2、修饰代码块
修饰代码块比修饰方法颗粒度更小。当实例方法代码块被synchronized修饰时,通过当前实例调用此方法的所有线程共用一把锁,不同对象调用此方法线程间互不影响。
public class B { public void func() { synchronized (this) { } }}
当使用synchronized锁修饰代码块,锁添加在当前类的实例上,有多少个实例可添加多少把锁。
3、修饰静态方法
当静态方法被synchronized修饰时,整个JVM所有调用此方法的线程均受同一个锁的约束。
public class C { public static synchronized void func() { }}
当使用synchronized锁修饰静态方法,锁添加在当前类的类对象
上,最多添加一把锁。
非必要不使用synchronized修饰静态方法
三、锁的升级
Java 8所使用的synchronized锁是经过优化后的,存在偏向锁
、轻量级锁
、重量级锁
等状态。
(一)偏向锁
线程间不存在锁的竞争行为,至多只有一个线程有获取锁的需求,常见场景为单线程程序
。
1、识别方法
判断是不是偏向锁的标识是查看调用此方法的线程是否有且仅有一个。
在多线程编程里,被锁修饰的方法仅被单一线程调用几乎不存在,因此偏向锁比较鸡肋:如果能够明确单一线程调用目标方法,使用无锁编程更为合适。
2、性能比较
无锁与偏向锁的性能差异非常接近,几乎可以忽略不计。
(二)轻量级锁
线程间存在锁的伪竞争行为
,即同一时刻绝对不会存在两个线程申请获取锁,各线程尽管都有使用锁的需求,但是是交替使用锁。
1、识别方法
当有两个及以上线程调用被锁修饰的方法时,那么至少能确定是轻量级锁。
2、性能比较
轻量级锁由于同一时刻不存在两个线程互相竞争锁,因此不存在线程阻塞-唤醒
的上下文切换,因此性能相对重量级锁要高很多。
(三)重量级锁
线程间存在锁的实质性竞争
行为,线程间都有获取锁的需求,但是时间不可交错,互斥锁的阻塞等待。
1、识别方法
当能够肯定至少有两个及以上线程调用被锁修饰的方法时,线程调用方法是随机的,那么大概率是重量级锁。
2、性能比较
重量级锁由于涉及到线程阻塞-唤醒的上下文切换,造成相比较与无锁状态,效率低很多。
四、其它内容
(一)锁的性质
1、公平性
synchronized锁是非公平锁
,没有FIFO队列机制保障竞争锁的线程一定有几率获得锁。
2、重入性
synchronized锁是可重入锁
,可重入意味着嵌套调用不会产生死锁问题。
3、乐(悲)观锁
synchronized锁是一种悲观锁,通过加锁实现线程间同步。
(二)理解重量级锁
在多线程环境下,如果使用synchronized锁,那么大概率会升级到重量级锁。偏向锁和轻量级锁非刻意为之,很难存在,更大的意义是对比帮助理解重量级锁的性能。
重量级锁尽管会对性能产生很大影响,但是依旧是解决线程间同步的有效手段。
1、选用锁的建议
当被锁修饰的方法或者代码块执行时间较长
时,选用基于线程阻塞-唤醒切换上下文的方式进行线程同步效率相对较高。
当被锁修饰的方法或者代码块执行时间较短
时,应选用其它替代锁,比如自旋锁等。
(三)理解synchronized锁
在实际多线程场景开发中,synchronized
锁大概率会升级到重量级锁,因其单向升级的特点,重量级状态的synchronized
锁可能会对实际业务的并发产生不利影响,手动选用其它锁可能会更合适。
synchronized
锁仅可用于解决同一进程内不同线程间同步,对于分布式项目跨进城线程同步依赖于分布式锁,synchronized
锁更多的意义是理解锁的过程。
喜欢本文点个️赞️支持一下,如有需要,可通过微信
dream4s
与我联系。相关源码在GitHub,视频讲解在B站,本文收藏在博客天地。
版权声明
本文为[Java知识图谱]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/5635240/blog/5517604
边栏推荐
- LeetCode 447. Number of boomerangs (permutation and combination problem)
- EBS:PO_ EMPLOYEE_ HIERARCHIES_ ALL
- On LAN
- [leetcode daily question] 396 Rotation function
- php 2022年4月20面试题整理
- Is the availability of proxy IP equal to the efficiency of proxy IP?
- Analyze the advantages and disadvantages of tunnel proxy IP.
- 006_ redis_ Jedis quick start
- 89 régression logistique prédiction de la réponse de l'utilisateur à l'image de l'utilisateur
- 关于局域网浅谈
猜你喜欢
Leetcode39 combined sum
Chinese scientists reveal a new mechanism for breaking through the bottleneck of rice yield
006_ redis_ Jedis quick start
Dynamic batch processing and static batch processing of unity
How to set computer IP?
The importance of ERP integration to the improvement of the company's system
005_redis_set集合
009_ Redis_ Getting started with redistemplate
What is a dial-up server and what is its use?
LeetCode 447. Number of boomerangs (permutation and combination problem)
随机推荐
Today will finally write system out. Println()
都是做全屋智能的,Aqara和HomeKit到底有什么不同?
If 404 page is like this | daily anecdotes
2018 China Collegiate Programming Contest - Guilin Site J. stone game
今天终于会写System.out.println()了
leetcode:27. 移除元素【count remove小操作】
Gray scale range corresponding to colors (red, yellow, green, blue, purple, pink, brick red and magenta) in HSV color space
What is a proxy IP pool and how to build it?
easyswoole环境配置
Startup of openstack service
011_RedisTemplate操作Hash
App optimization and advanced scoreboard Part 2 [Mui + flask + mongodb]
Nanny level tutorial on building personal home page (II)
What is BGP server and what are its advantages?
Shardingsphere sub database and sub table
leetcode:27. Remove element [count remove]
配置iptables实现本地端口转发的方法详解
Consider defining a bean of type ‘com.netflix.discovery.AbstractDiscoveryClientOptionalArgs‘
想体验HomeKit智能家居?不如来看看这款智能生态
001_redis设置存活时间