Java SE的每个版本都花费了大量的心思在同步性能优化上,Java SE 6也不例外。当多个线程需要同时访问共享的可变数据时,需要使用锁来同步多个线程的访问。根据竞争程度的不同,锁又可分为竞争性锁(contended lock)和非竞争性锁(uncontended lock)。由于大多数的锁都是非竞争性的,Java SE主要将精力用于优化非竞争性锁的性能,同时Java SE 6也优化了竞争性锁的性能。对竞争性锁优化的主要方法是自适应自旋(adaptive spinning),对非竞争性锁优化的方法有偏向性锁(Biased Locking)、锁粗化(Lock Coarsening)和锁取消(Lock Elision)。下面就一一谈下这四种优化同步性能的方法。
自适应自旋(adaptive spinning)
当两个线程竞争同一个锁时,其中一个线程获得锁,而另一个线程被阻塞直到锁被释放。通常的做法是操作系统悬挂起后一个线程,当前一个线程释放锁时唤醒后一个线程。这存在线程上下文切换的开销,另一种方法是后一个线程忙等待一段时间(通常就是几个时钟周期),这也就是自旋(spinning),当线程等待锁的时间极短时,这种方法比悬挂方法更有效率。Java SE 6使用自适应(adaptive)的技术进一步提高性能,它的主要思想是动态监控自旋成功/失败的比率,如果该几率比较大就使用自旋方法,否则就使用悬挂方法。自适应自旋技术主要是对多核系有效,它能避免使用悬挂方法所造成的线程上下文切换开销。
偏向性锁(Biased Locking)
偏向性锁主要基于这样的一个观察,一个锁在它的生命周期中通常只被一个线程所拥有。如果线程1拥有锁,这个锁就偏向(biase toward)于线程1,下次线程1需要再次获得锁时它就具有优先权。
注:偏向性锁对性能优化的原理我还并不是十分清楚,官方文章说偏向性锁能够避免一些原子操作,而这些原子操作十分耗时,但是我不明白为什么需要这些原子操作。这里的原子操作主要指的是CAS(Compare and Swap)。
锁粗化(Lock Coarsening)
当线程需要获得-释放锁,然后再获得-释放同一个锁,且第一次释放锁和第二交获得锁之间没有其它操作时,可以将两次获得-释放合并成一个获得-释放锁,这可以减少获得-释放锁的开销。例如,对下面的代码就可以使用锁粗化技术。
void addThing(StringBuffer buf) {
buf.append("thing 1");
buf.append("thing 2");
}
锁粗化带来的一个不好的效果就是线程占用锁的时间变长,这导致其他线程等待更长的时间。基于这种原因,锁粗化不能用于循环上。例如对于下面的代码就不能使用锁技术。
void addRepeatedThing(StringBuffer buf, int count) {
for (int i = 0; i < count; i++) {
buf.append("thing");
}
}
锁取消(Lock Elision)
有时我们可以通过逸出分析(escape analysis)确定这个锁只能在一个线程使用,这时锁不起任何作用,可以完全取消这个锁。比如下面的锁就可以完全去掉,因为new Object()只能在一个线程中使用,别的线程不能访问到这个锁。
synchronized (new Object()) {
doSomeThing();
}
上面是个伪造的例子,下面是个更加实际的例子。在这个例子中,StringBuffer对象sb是个局部变量,只能被当前线程所访问,因此对sb的所有操作都可以安全地取消掉同步,通过这种方法StringBuffer可以达到和StringBuilder几乎一样的性能。
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("field1: ").append(field1);
sb.append(", field2: ").append(field2);
return sb.toString();
}
分享到:
- 2009-03-04 01:07
- 浏览 1801
- 评论(0)
- 论坛回复 / 浏览 (0 / 1858)
- 查看更多
相关推荐
在JVM层面,Java SE6改进了垃圾收集算法,如ParNew和CMS(Concurrent Mark Sweep),提供了更好的内存管理和性能优化。同时,JMX(Java Management Extensions)的增强使得系统管理和监控更为便捷。 总的来说,...
Java SE6(Java Platform Standard Edition 6)是一款旨在优化性能与可扩展性的Java版本。为了实现这一目标,Sun Microsystems紧密合作Java社区,并借助一系列基准测试来识别并解决影响性能的关键领域。本白皮书重点...
Java SE7引入了Fork/Join框架,优化了并行计算,同时对锁和同步进行了改进,如轻量级锁和自旋锁。 8. **动态类型**:Java SE7引入了`钻石操作符`(`<>`),简化了匿名内部类和泛型的使用,以及`try-with-resources`...
这个版本在2006年发布,对Java开发者来说是一个重要的里程碑,因为它引入了许多新特性,改进了性能,并优化了开发体验。 在"Java SDK SE6 教學"中,我们可以期待学习以下几个关键知识点: 1. **JDK安装与环境配置*...
- Java SE 12引入了新的性能优化特性,如JIT编译器的改进,更高效的内存分配和垃圾收集策略。 - 垃圾收集器如G1、ZGC和Shenandoah提供了低暂停时间的选择,提高了应用的响应性。 7. **异常处理和线程**: - JVM...
12. **JVM优化**:文档会涵盖JVM(Java Virtual Machine)的内存管理、垃圾回收、性能监控和调优技巧,帮助开发者提高程序的运行效率。 Java SE 6的官方帮助文档,不仅是初学者的宝典,也是经验丰富的开发者的重要...
5. **多线程**:Java SE 6提供了强大的多线程支持,包括线程的创建、同步、协作等。ExecutorService和Future接口的引入,使得线程池的管理和任务调度更为便捷。 6. **输入/输出流**:Java的I/O流系统广泛用于数据的...
6. **内存模型与并发**:Java内存模型(JMM)定义了线程之间共享变量的访问规则,确保正确同步和内存可见性。它涉及到volatile变量、synchronized关键字、final字段的语义以及线程交互的内存操作。 7. **异常处理**...
"u144"代表这是一个更新版本,即第144次更新,通常包含安全修复、性能优化和新功能。 文档是学习和理解任何编程平台或库的关键资源,Java SE Development Kit 8u144的文档详细阐述了该版本的各个方面,包括API参考...
JDK 8u321作为维护更新版本,主要关注性能优化、安全修复和稳定性提升。这些更新对于保持应用程序的可靠性和安全性至关重要,尤其是在企业级环境中,安全性和稳定性是首要考虑的因素。此外,更新可能还会包括对Java...
此外,理解JVM(Java虚拟机)的工作原理,包括内存模型、垃圾回收、性能优化等,对于写出高效、稳定的Java程序极其关键。课件中可能有专门的章节介绍JVM相关知识。 最后,实战项目经验是巩固理论知识的最佳途径。...
Java SE(标准版)是Java开发平台的核心,它包含了...通过深入学习这些源码,开发者可以提升对Java的理解,优化代码性能,甚至为Java社区贡献自己的改进。记住,源码是学习的最好教材,它揭示了软件设计的智慧和匠心。
12. **性能优化与调试技巧**:分享提高Java程序性能的方法和常用的调试技巧。 13. **高级主题**:涉及一些更高级的主题,如注解、反射、动态代理等。 #### 五、学习方法与建议 - **理论与实践相结合**:在学习理论...
《Java语言规范,Java SE 11版》是Java开发者不可或缺的重要参考资料,它详细定义了Java 11的语法、语义以及编程模型。这份规范是理解Java平台核心特性的基石,涵盖了从基本类型到复杂类结构,从内存管理到异常处理...
总的来说,Java Virtual Machine Specification Java SE 7 中文版详细阐述了Java虚拟机在Java SE 7版本中的各项特性和实现细节,对于理解Java程序的运行机制、优化代码性能以及深入学习Java平台具有重要价值。...
这份文档对于理解Java程序的执行机制、性能优化和故障排查具有极高的价值。 1. **JVM结构**:JVM由类加载器、运行数据区、执行引擎、本地方法接口和本地方法库五个主要部分组成。类加载器负责加载字节码文件,运行...
Java虚拟机(JVM)是Java程序运行的...以上只是《Java虚拟机规范 Java SE 7中文版》中部分关键知识点的概述,深入学习和理解这些内容,对于提升Java开发者的技能水平,优化代码性能,以及解决实际问题都有极大的帮助。
在Java SE 7版本中,JVM进行了一些重要的改进和优化,使得Java应用程序的性能得到提升,同时增强了开发者的编程体验。 1. 类加载机制:JVM按照“加载、验证、准备、解析、初始化”的顺序来处理类。Java SE 7引入了...
7. **Java性能优化**: - 内存管理,避免内存泄漏,减少不必要的对象创建。 - 使用StringBuilder或StringBuffer代替字符串连接操作。 - 避免过度使用同步,考虑使用并发工具类(如ConcurrentHashMap)。 8. **...