Java - synchronized
2020-04-07 本文已影响0人
万福来
synchronized
synchronized是jvm提供的一种用来进行并发控制的多线程锁;synchronized是基于进入和退出monitor对象来实现方法同步和代码块同步的,每一个java对象都可以作为synchronized的锁对象。
synchronized三种用法
- 普通对象的同步方法,锁是当前实例对象;
- 静态同步方法,锁是当前class对象;
- 同步方法块,锁是括号里的对象;
synchronized的实现。
JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。代码块同步是使用monitorenter和monitorexit指令实现的,monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处。任何对象都有一个monitor与之关联,当且一个monitor被持有后,它将处于锁定状态。
根据虚拟机规范的要求,在执行monitorenter指令时,首先要去尝试获取对象的锁,如果这个对象没被锁定,或者当前线程已经拥有了那个对象的锁,把锁的计数器加1;相应地,在执行monitorexit指令时会将锁计数器减1,当计数器被减到0时,锁就释放了。如果获取对象锁失败了,那当前线程就要阻塞等待,直到对象锁被另一个线程释放为止。
synchronized的优化状态
锁状态 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
偏向锁 | 加锁状态不需要其他消耗 | 如果存在锁竞争,会带来额外锁撤销 | 适用于只有一个线程 |
轻量级锁 | 竞争线程不会阻塞,提高程序响应 | 始终得不到锁的线程,会自旋消耗CPU | 适用低延时 |
重量级锁 | 线程竞争不会自旋消耗CPU | 线程阻塞,响应时间慢 | 适用高吞吐量 |