五、synchronized

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五、synchronized相关的知识,希望对你有一定的参考价值。

参考技术A synchronized在jdk1.5前只有重量级锁,开销较大。为了应对低竞争的场景在jdk1.5增加了偏向锁和轻量级锁。对象的锁状态通过对象头里的markword标识。

1)场景:在一个时刻只有一个线程请求锁,没有竞争;
2)关键参数:
-XX:+UseBiasedLocking # 是否开启偏向锁,jdk1.6以后默认开启
-XX:BiasedLockingStartupDelay=4000 # 偏向锁延迟启动时间,
-XX:BiasedLockingDecayTime=25000 # 重置撤销次数的时间阈值
-XX:BiasedLockingBulkRevokeThreshold=40 # 偏向锁批量撤销阈值
-XX:BiasedLockingBulkRebiasThreshold=20 # 偏向锁批量重偏向阈值

Note:

3)实现原理:markword标识出偏向锁状态,且保存当前持有锁的线程ID。然后在其线程栈上隐式保存递归次数。

4)优点:在无竞争的情况下开销较小,包括cpu(无须切换上下文和线程调度)和内存(无须分配管程对象)开销。
5)缺点:锁撤销开销较大,需要挂起锁定线程,遍历其线程栈,修改锁记录。甚至比轻量级锁和重量级锁的开销还大。目前HotSpot使用安全点的STW和启发式撤销方法,减少撤销次数,提高性能。
6)可重偏向的条件

Note1: 当类元数据中的epoch与类对象的对象头中的epoch值相等时,表示当前偏向锁有效;否则该偏向锁失效,可重偏向;通过引入epoch减小了重偏向的开销;

Note2:在调用hashcode时会撤销偏向锁来还原hashcode的占位;
Note3: 调用wait,notify会膨胀为重量级锁。触发管程对象分配和初始化;

1)场景:在一段时间内请求的锁的线程较少,且持有锁的线程执行时间短,持有锁的时间短,其他等待线程在有限的自旋等待期可以得到锁。
2)实现结构——栈上锁记录

3)锁升级过程

Note1: 调用wait,notify会膨胀为重量级锁。触发管程对象分配和初始化;

1)管程对象——monitor
通过对象关联的管程对象实现线程阻塞,唤醒机制。其主要依赖操作系统级的互斥量来实现。
2)WaitSet,EntrySet

3)优点:
在多线程并发激烈的情况下性能表现好,让未获得锁的线程让出时间片和cpu使用权,减少资源消耗。

ReentrantLock优点:

Java Thread系列synchronized

Java Thread系列(五)synchronized

synchronized锁重入

关键字 synchronized 拥有锁重入的功能,也就是在使用 synchronized 时,当线程等到一个对象的锁后,再次请求此对象时可以再次得到该对象的锁。出现异常时释放锁。

synchronized异常

synchronized代码块

使用 synchronized 声明的方法在某些情况下是有弊端的,比如A线程调用同步的方法执行一个很长时间的任务,那么B线程就必须等待比较长的时间才能执行,这样的情况下可以使用 synchronized 代码块去优化代码执行时间,也就是通常所说的减小锁的粒度。

synchronized代码块案例 【com.herolei._1_2sync.ObjectLock】

synchronized对常量加锁的问题 【com.herolei._1_2sync.StringLock】

注意:锁对象发生改变问题,当使用一个对象进行加锁的操作,要注意对象本身发生改变的时候,那么持有的锁就不同。


每天用心记录一点点。内容也许不重要,但习惯很重要!

以上是关于五、synchronized的主要内容,如果未能解决你的问题,请参考以下文章

线程锁

锁之synchronized

synchronized

Synchronized

synchronized

关键字: synchronized详解