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

Posted

篇首语:谨慎和勤奋带来好运。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java 6中的线程优化真的有效么相关的知识,希望对你有一定的参考价值。

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

  简析锁粗化(Lock coarsening explained)

  另一种线程优化方式是锁粗化(或合并 merging) 当多个彼此靠近的同步块可以合并到一起 形成一个同步块的时候 就会进行锁粗化 该方法还有一种变体 可以把多个同步方法合并为一个方法 如果所有方法都用一个锁对象 就可以尝试这种方法 考虑图 中的实例

 public static String concatToBuffer(StringBuffer sb String s String s String s ) sb append(s );sb append(s );sb append(s );return

  在这个例子中 StringBuffer的作用域是非局部的 可以被多个线程访问 所以逸出分析会判断出StringBuffer的锁不能安全地被忽略 如果锁刚好只被一个线程访问 则可以使用偏向锁 有趣的是 是否进行锁粗化 与竞争锁的线程数量是无关的 在上面的例子中 锁的实例会被请求四次 前三次是执行append方法 最后一次是执行toString方法 紧接着前一个 首先要做的是将这种方法进行内联 然后我们只需执行一次获取锁的操作(为整个方法) 而不必像以前一样获取四次锁了

  这种做法带来的真正效果是我们获得了一个更长的临界区 它可能导致其他线程受到拖延从而降低吞吐量 正因为这些原因 一个处于循环内部的锁是不会被粗化到包含整个循环体的

  线程挂起 vs 自旋(Thread suspending versus spinning)

  在一个线程等待另外一个线程释放某个锁的时候 它通常会被操作系统挂起 操作在挂起一个线程的时候需要将它换出CPU 而通常此时线程的时间片还没有使用完 当拥有锁的线程离开临界区的时候 挂起的线程需要被重新唤醒 然后重新被调用 并交换上下文 回到CPU调度中 所有这些动作都会给JVM OS和硬件带来更大的压力

  在这个例子中 如果注意到下面的事实会很有帮助 锁通常只会被占有很短的一段时间 这就是说 如果能够等上一会儿 我们可以避免挂起线程的开销 为了让线程等待 我们只需将线程执行一个忙循环(自旋) 这项技术就是所谓的自旋锁

  当锁被占有的时间很短时 自旋锁的效果非常好 另一方面 如果锁被占有很长时间 那么自旋的线程只会消耗CPU而不做任何有用的工作 因此带来浪费 自从JDK 中引入自旋锁以来 自旋锁被分为两个阶段 自旋十个循环(默认值) 然后挂起线程

  自适应自旋锁(Adaptive spinning)

  JDK 中引入了自适应自旋锁 自适应意味着自旋的时间不再固定了 而是取决于一个基于前一次在同一个锁上的自旋时间以及锁的拥有者的状态 如果在同一个锁对象上 自旋刚刚成功过 并且持有锁的线程正在运行中 那么自旋很有可能再次成功 进而它将被应用于相对更长的时间 比如 个循环 另一方面 如果自旋很少发生过 它将被遗弃 避免浪费任何CPU周期

  StringBuffer vs StringBuilder的基准测试

  但是要想设计出一种方法来判断这些巧妙的优化方法到底多有效 这条路并不平坦 首要的问题就是如何设计基准测试 为了找到问题的答案 我决定去看看人们通常在代码中运用了哪些常见的技巧 我首先想到的是一个非常古老的问题 使用StringBuffer代替String可以减少多少开销?

  一个类似的建议是 如果你希望字符串是可变的 就应该使用StringBuffer 这个建议的缘由是非常明确的 String是不可变的 但如果我们的工作需要字符串有很多变化 StringBuffer将是一个开销较低的选择 有趣的是 在遇到JDK 中的StringBuilder(它是StringBuffer的非同步版本)后 这条建议就不灵了 由于StringBuilder与 StringBuffer之间唯一的不同在于同步性 这似乎说明 测量两者之间性能差异的基准测试必须关注在同步的开销上 我们的探索从第一个问题开始 非竞争锁的开销如何?

  这个基准测试的关键(如清单 所示)在于将大量的字符串拼接在一起 底层缓冲的初始容量足够大 可以包含三个待连接的字符串 这样我们可以将临界区内的工作最小化 进而重点测量同步的开销

  基准测试的结果

  下图是测试结果 包括EliminateLocks UseBiasedLocking和DoEscapeAnalysis的不同组合

图 基准测试的结果

cha138/Article/program/Java/gj/201311/27670

相关参考

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

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

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

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

知识大全 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线程池需