synchronized原理和锁优化

1 synchronized原理
synchronized关键字编译后会在同步块的前后添加上montorenter和monitorexit两个字节码指令,这两个字节码指令都需要一个指向锁定和解锁对象的reference,如果指定了同步的对象reference就指向这个对象,如果修饰的是方法,如果是类方法就指向Class对象,如果是实例方法就指向这个实例。
2线程安全
2.1定义
当多线程访问一个对象时,如果不需要考虑多线程的调度和交替执行,也不需要进行额外的同步,或者在调用方进行额外的协调操作,调用这个对象的行为都可以获得正确的结果,就可以说这个对象是线程安全的。

2.2原子性
java内存模型直接保证的原子性包括:read load use assign store write这6个,另外synchronized之间的操作也具备原子性。

2.3可见性
可见性指一个线程修改了共享变量的值,另外一个线程立即能够获得这个修改。
volatile通过修改后能够立即同步回主内存,使用之前必须从主内存刷新,保证了可见性。
synchronized和final变量也保证了可见性。

2.4有序性
同一个线程内,所有操作都是有序的,从一个线程观察另外一个线程,都是无序的。
synchronized 可以保证同一个锁的同步块只能串行进入。


3 synchronized缺点
synchronized是一种悲观锁,锁存的的问题:
1.多线程竞争的情况下,频繁的加锁解锁导致过多的线程上下文切换,由于java线程是基于操作系统内核线程实现的,所以如果阻塞或者唤醒线程都需要切换到内核态操作,这需要耗费许多CPU时钟。
2.一个线程持有锁,会导致其他请求该锁的线程挂起。
3.如果高优先级线程请求的锁,被低优先级线程占用,则会发生优先级倒置。

4锁优化
4.1 锁自旋
很多应用中共享数据的锁定,只会持续很多的一段时间,为了这很短的一段时间做线程的挂起和恢复,会造成很大的性能消耗,因为java线程对应操作系统的内核线程,要做挂起和恢复需要从用户态切换到通过系统调用完成,所以让后面请求锁的线程自旋一会。

4.2 锁消除
代码上要求同步,但是虚拟机检测到不存在共享数据竞争的情况下,会做锁消除。
有很多同步不是程序员自己加上的。

4.3 锁粗化
一般情况下锁应该范围尽可能的小。但是如果是循环内的锁,才可以通过锁粗化来避免频繁的加锁解锁消耗性能。
4.4 对象头
HotSpot虚拟机的对象头分为两部分,第一部分用于存储对象自身的运行时数据,如hashCode,GC分代年龄,官方称之为"mark word",第二部分用于存储指向方法区对象类型的指针,如果是数组类型的还有一个存储数组长度的部分。
其他状态下的mark word如下:

[img]http://dl2.iteye.com/upload/attachment/0104/0712/55e56721-135d-3618-8a04-2842a157e22b.png[/img]


4.5 偏向锁
Java SE1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”概念,Java SE1.6一共有4种状态,无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,他们会随着竞争情况不断升级,锁可以升级但是不能降级。

锁对象第一次被线程获取的时候,虚拟机把对象头的标识位设置为"01",可偏向模式,如果通过CAS操作把mark word设置为当前线程的ID,如果CAS操作成功,这样以后这个线程每次进入这个锁的同步块时,虚拟机不再进行任何操作。

一旦有其他线程竞争这个锁,则偏向模式宣布结束。
4.6 轻量级锁
代码进入同步块时,如果对象没有被锁定,虚拟机首先在当前线程的栈帧建立一个名为lock record的记录,存储锁对象目前的mark word,官方称之为displaced mark word。然后虚拟机通过CAS操作将对象头的mark word更新为指向lock record,如果成功则该线程或得了锁,如果失败,则膨胀为重量级锁。

堆栈与对象的状态如下图所示:

[img]http://dl2.iteye.com/upload/attachment/0104/0710/101d8722-deb2-352f-b256-93cb14fefe55.png[/img]

4.7 各自的适用场景

[img]http://dl2.iteye.com/upload/attachment/0104/0714/be7c4eec-8cc7-3c58-baa6-8a3b754d1b65.png[/img]


5参考资料
http://www.infoq.com/cn/articles/java-se-16-synchronized
http://www.iteye.com/topic/806990
深入理解Java虚拟机:JVM高级特性与最佳实践 -周志明 *
http://blog.csdn.net/chenghai2011/article/details/8009983
http://wenku.baidu.com/link?url=mURhBANj9nJVdmtY9bfAnZ01qs-mTeeNZl_hF7TxAoiFW3sAoeaLGCIjcehTG7aSn0Ho_FApYB_raIKOdd0TaUI80T2tKCCbsVupLw4nduy *
http://zxf-noimp.iteye.com/blog/1050261
http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值