转载请注明原文地址: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操作来获得锁,如果轻量级锁获得失败,说明存在竞争。但是也许很快就能获得锁,就会尝试自旋锁,将线程做几个空循环,每次循环时都不断尝试获得锁。如果自旋锁也失败,那么只能升级成重量级锁。

Java多线程之锁优化策略的更多相关文章

  1. java多线程编程——锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  2. Java多线程编程 — 锁优化

      阅读目录 一.尽量不要锁住方法 二.缩小同步代码块,只锁数据 三.锁中尽量不要再包含锁 四.将锁私有化,在内部管理锁 五.进行适当的锁分解 正文 并发环境下进行编程时,需要使用锁机制来同步多线程间 ...

  3. Java多线程编程—锁优化

    并发环境下进行编程时,需要使用锁机制来同步多线程间的操作,保证共享资源的互斥访问.加锁会带来性能上的损坏,似乎是众所周知的事情.然而,加锁本身不会带来多少的性能消耗,性能主要是在线程的获取锁的过程.如 ...

  4. JAVA多线程与锁机制

    JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...

  5. Java 多线程:锁(二)

    Java 多线程:锁(二) 作者:Grey 原文地址: 博客园:Java 多线程:锁(二) CSDN:Java 多线程:锁(二) AtomicLong VS LongAddr VS Synchroni ...

  6. Java 虚拟机对锁优化所做的努力

    作为一款公用平台,JDK 本身也为并发程序的性能绞尽脑汁,在 JDK 内部也想尽一切办法提供并发时的系统吞吐量.这里,我将向大家简单介绍几种 JDK 内部的 "锁" 优化策略. 1 ...

  7. Java 多线程:锁(一)

    Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...

  8. Java 多线程:锁(三)

    Java 多线程:锁(三) 作者:Grey 原文地址: 博客园:Java 多线程:锁(三) CSDN:Java 多线程:锁(三) StampedLock StampedLock其实是对读写锁的一种改进 ...

  9. 深入理解多线程(五)—— Java虚拟机的锁优化技术

    本文是<深入理解多线程>的第五篇文章,前面几篇文章中我们从synchronized的实现原理开始,一直介绍到了Monitor的实现原理. 前情提要 通过前面几篇文章,我们已经知道: 1.同 ...

随机推荐

  1. 明日传奇第三季/全集Legends of Tomorrow迅雷下载

    <明日传奇>第三季将加入一名新的女性角色.据Variety得到的消息称,塔拉·阿什(Tala Ashe)将作为<明日传奇>第三季的常规演员加入该剧.在第三季中,塔拉·阿什饰演的 ...

  2. iTunes Connect开发者指南中的一个疑问

    iTunes Connect Developer Guide     避免app版本出现在iClound中,我的疑问是对已经上架的版本不能设置,那么这个功能的真正意义在哪里? 大部分用户去应用页面下载 ...

  3. Spring data jpa Specification查询关于日期的范围搜索

    代码: 时间格式化类型: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat s ...

  4. you have mixed tabs and spaces fix this

    http://blog.csdn.net/tonyyan19781/article/details/60882443 Vs2013 IDE下,编辑C++的工程源码,在打开文件的时候,会出现 " ...

  5. NLP的神经网络训练的新模式

    https://blog.csdn.net/jdbc/article/details/53292414 该模式分为:embed.encode.attend.predict四部分.

  6. JavaScript递归方法 生成 json tree 树形结构数据

    //递归方法 生成 json tree 数据 var getJsonTree = function(data, parentId) { var itemArr = []; for (var i = 0 ...

  7. 一些非常实用的JSON 教程

    以下内容来自W3school. JSON:JavaScript 对象表示法(JavaScript Object Notation). JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 ...

  8. svg image标签降级技术

    1.svg image标签降级技术: svg不能很好的在anroid2.3中得到支持,需要额外的补充,IE8-以及Android 2.3默认浏览器是不支持SVG的. svg image标签降级技术,这 ...

  9. Android 混合式开发AppCan介绍

    Android程序员开发已从最早的异常火热到现在已经逐渐趋向稳定,目前企业针对Android开发工程师的要求要求已逐步提高,现在想从众多的面试者中脱颖而出,必须打好坚实的代码基础. 今天为大家介绍一款 ...

  10. bp算法中为什么会产生梯度消失?

    作者:维吉特伯链接:https://www.zhihu.com/question/49812013/answer/148825073来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...