转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561264.html 

锁的优化策略

编码过程中可采取的锁优化的思路有以下几种:

1:减少锁持有时间

例如:对一个方法加锁,不如对方法中需要同步的几行代码加锁;

2:减小锁粒度

例如:ConcurrentHashMap采取对segment加锁而不是整个map加锁,提高并发性;

3:锁分离

根据同步操作的性质,把锁划分为的读锁和写锁,读锁之间不互斥,提高了并发性。

4:锁粗化

这看起来与思路1有冲突,其实不然。思路1是针对一个线程中只有个别地方需要同步,所以把锁加在同步的语句上而不是更大的范围,减少线程持有锁的时间;

而锁粗化是指:在一个间隔性地需要执行同步语句的线程中,如果在不连续的同步块间频繁加锁解锁是很耗性能的,因此把加锁范围扩大,把这些不连续的同步语句进行一次性加锁解锁。虽然线程持有锁的时间增加了,但是总体来说是优化了的。

5:锁消除

锁消除是编译器做的事:根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程(即不会影响线程空间外的数据),那么可以认为这段代码是线程安全的,不必要加锁。

Java虚拟机中采取的锁优化策略:

1:偏向锁:锁对象偏向于当前获得它的线程,如果在接下来的没有被其他线程请求,则持有该锁的线程将不再需要进行同步操作(即:持有该锁的线程在接下来的执行中遇到同步块时不再需要lock和unlock了,直接执行即可)。当另一个线程申请该锁时,当前线程的偏向模式才会结束,让出该锁。

2:轻量级锁:syncrhoized的底层实现是通过监视器monitor来控制的,而monitorenter与monitorexit这两个原语是依赖操作系统互斥(mutex)来实现的。

互斥会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源。轻量级锁(Lightweight Locking)利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救,减少多线程进入互斥的几率。

如果偏向锁失败,那么系统会进行轻量级锁的操作,使用CAS操作来尝试加锁。如果轻量级锁失败,才调用系统级别的重量级锁(syncrhoized)来加锁。

3:自旋锁:当线程申请锁时,锁被占用,则让当前线程执行一个忙循环(自旋),看看持有锁的线程是否会很快释放锁。如果自旋后还没获得锁,才进入同步阻塞状态;

3.1:自适应自旋:自旋的线程自旋的时间为同一个锁上一次线程自旋并获得锁的耗时。如果对于这个锁,自旋很少有成功的,就不自旋了,避免浪费CPU资源。

为了尽量避免使用重量级锁(操作系统层面的互斥),JVM首先会尝试轻量级锁,轻量级锁会尝试使用CAS操作来获得锁,如果轻量级锁获得失败,说明存在竞争。但是也许很快就能获得锁,就会尝试自旋锁,将线程做几个空循环,每次循环时都不断尝试获得锁。如果自旋锁也失败,那么只能升级成重量级锁。

最新文章

  1. CozyRSS开发记录10-RSS源管理
  2. ReactiveCocoa源码拆分解析(七)
  3. BAT技巧
  4. DateTime与DateTime?赋值问题以及null类型的如何赋值问题
  5. 使用windbg查看DependencyObject的属性
  6. jsDoc的使用
  7. Insert Interval
  8. php 读取文件头判断文件类型的实现代码
  9. Android:EditText 常用属性
  10. [Everyday Mathematics]20150111
  11. InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
  12. 如何解决Windows8.1(32bit&64bit)下Cisco VPN Client拨号时报442错误的问题
  13. js监听浏览器离开页面操作
  14. jquery 设置占位符
  15. MVC图片上传详解
  16. AX_SysTableBrowser
  17. Android cannot be cast to android.app.Fragment
  18. 转载别人的一篇关于git的文章
  19. leetCode题解之Array Partition I
  20. 【bzoj2844】albus就是要第一个出场

热门文章

  1. 你真的懂Handler.postDelayed()的原理吗?
  2. python的日志模块:logging;django的日志系统;django日志输出时间修改
  3. 什么是 Event Loop?
  4. hdu 2544 单源最短路问题 dijkstra+堆优化模板
  5. scrapy框架系列 (5) Spider类
  6. 在springboot项目中使用mybatis 集成 Sharding-JDBC
  7. CentOS中zip压缩和unzip解压缩命令详解
  8. windows下mysql忘记root密码的解决办法
  9. SQL Server 2005 Integration Services (SSIS)数据源之MySQL
  10. 推荐系统resys小组线下活动见闻2009-08-22