知识大全 Java 6中的线程优化真的有效么

Posted

篇首语:天才是百分之九十九的汗水加百分之一的灵感。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java 6中的线程优化真的有效么相关的知识,希望对你有一定的参考价值。

Java 6中的线程优化真的有效么?[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  介绍 — Java 中的线程优化   

  Sun IBM BEA和其他公司在各自实现的Java 虚拟机上都花费了大量的精力优化锁的管理和同步 诸如偏向锁(biased locking) 锁粗化(lock coarsening) 由逸出(escape)分析产生的锁省略 自适应自旋锁(adaptive spinning)这些特性 都是通过在应用程序线程之间更高效地共享数据 从而提高并发效率 尽管这些特性都是成熟且有趣的 但是问题在于 它们的承诺真的能实现么?在这篇由两部分组成的文章里 我将逐一探究这些特性 并尝试在单一线程基准的协助下 回答关于性能的问题

  悲观锁模型

  Java支持的锁模型绝对是悲观锁(其实 大多数线程库都是如此) 如果有两个或者更多线程使用数据时会彼此干扰 这种极小的风险也会强迫我们采用非常严厉的手段防止这种情况的发生——使用锁 然而研究表明 锁很少被占用 也就是说 一个访问锁的线程很少必须等待来获取它 但是请求锁的动作将会触发一系列的动作 这可能导致严重的系统开销 这是不可避免的

  我们的确还有其他的选择 举例来说 考虑一下线程安全的StringBuffer的用法 问问你自己 是否你曾经明知道它只能被一个线程安全地访问 还是坚持使用StringBuffer 为什么不用StringBuilder代替呢?

  知道大多数的锁都不存在竞争 或者很少存在竞争的事实对我们作用并不大 因为即使是两个线程访问相同数据的概率非常低 也会强迫我们使用锁 通过同步来保护被访问的数据 我们真的需要锁么? 这个问题只有在我们将锁放在运行时环境的上下文中观察之后 才能最终给出答案 为了找到问题的答案 JVM的开发者已经开始在HotSpot和JIT上进行了很多的实验性的工作 现在 我们已经从这些工作中获得了自适应自旋锁 偏向锁和以及两种方式的锁消除(lock elimination)——锁粗化和锁省略(lock elision) 在我们开始进行基准测试以前 先来花些时间回顾一下这些特性 这样有助于理解它们是如何工作的

  逸出分析 — 简析锁省略(Escape analysis lock elision explained)

  逸出分析是对运行中的应用程序中的全部引用的范围所做的分析 逸出分析是HotSpot分析工作的一个组成部分 如果HotSpot(通过逸出分析)能够判断出指向某个对象的多个引用被限制在局部空间内 并且所有这些引用都不能 逸出 到这个空间以外的地方 那么HotSpot会要求JIT进行一系列的运行时优化 其中一种优化就是锁省略(lock elision) 如果锁的引用限制在局部空间中 说明只有创建这个锁的线程才会访问该锁 在这种条件下 同步块中的值永远不会存在竞争 这意味这我们永远不可能真的需要这把锁 它可以被安全地忽略掉 考虑下面的方法

 publicString concatBuffer(String s String s String s ) StringBuffer sb = new StringBuffer();sb append(s );sb append(s );sb append(s );return sb toString();   

  如果我们观察变量sb 很快就会发现它仅仅被限制在concatBuffer方法内部了 进一步说 到sb的所有引用永远不会 逸出 到 concatBuffer方法之外 即声明它的那个方法 因此其他线程无法访问当前线程的sb副本 根据我们刚介绍的知识 我们知道用于保护sb的锁可以忽略掉

  从表面上看 锁省略似乎可以允许我们不必忍受同步带来的负担 就可以编写线程安全的代码了 前提是在同步的确是多余的情况下 锁省略是否真的能发挥作用呢?这是我们在后面的基准测试中将要回答的问题

  简析偏向锁(Biased locking explained)

  大多数锁 在它们的生命周期中 从来不会被多于一个线程所访问 即使在极少数情况下 多个线程真的共享数据了 锁也不会发生竞争 为了理解偏向锁的优势 我们首先需要回顾一下如何获取锁(监视器)

  获取锁的过程分为两部分 首先 你需要获得一份契约 一旦你获得了这份契约 就可以自由地拿到锁了 为了获得这份契约 线程必须执行一个代价昂贵的原子指令 释放锁同时就要释放契约 根据我们的观察 我们似乎需要对一些锁的访问进行优化 比如线程执行的同步块代码在一个循环体中 优化的方法之一就是将锁粗化 以包含整个循环 这样 线程只访问一次锁 而不必每次进入循环时都进行访问了 但是 这并非一个很好的解决方案 因为它可能会妨碍其他线程合法的访问 还有一个更合理的方案 即将锁偏向给执行循环的线程

  将锁偏向于一个线程 意味着该线程不需要释放锁的契约 因此 随后获取锁的时候可以不那么昂贵 如果另一个线程在尝试获取锁 那么循环线程只需要释放契约就可以了 Java 的HotSpot/JIT默认情况下实现了偏向锁的优化

cha138/Article/program/Java/gj/201311/27671

相关参考

知识大全 Java 6中的线程优化真的有效么

Java6中的线程优化真的有效么?[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  运行基准

知识大全 Java 6中的线程优化真的有效么

Java6中的线程优化真的有效么?[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  简析锁粗

知识大全 Java 6中的性能优化

Java6中的性能优化  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  JSE(代号Mustang

知识大全 Java中的线程组

Java中的线程组  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  所有线程都隶属于一个线程组那可

知识大全 Java线程模型缺陷研究[6]

Java线程模型缺陷研究[6]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  

知识大全 java多线程中的异常处理

  在java多线程程序中所有线程都不允许抛出未捕获的checkedexception也就是说各个线程需要自己把自己的checkedexception处理掉这一点是通过javalangRunnable

知识大全 JAVA多线程中的锁机制

JAVA多线程中的锁机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  JAVA中的每个对象都可

知识大全 Java线程通信源代码中的奥秘探究

Java线程通信源代码中的奥秘探究  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线程通

知识大全 Java线程池在使用中的问题解疑

Java线程池在使用中的问题解疑  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Java线程池需