第10章 避免活跃度危险
1. 锁顺序死锁
如果多个线程试图通过不同的顺序获得多个相同的锁,则会发生死锁。
如果所有线程以通用的固定秩序获得锁,程序就不会出现锁顺序死锁问题了。
2. 动态的锁顺序死锁
3. 协作对象间的死锁
当外部方法被调用时正持有锁,则其可能会获得其他锁(产生死锁的危险),或者遭遇严重超时的阻塞。当你持有锁的时候会延迟其他试图获得该锁的线
程。
4. 开放调用
当调用的方法不需要持有锁时,这被称为开放调用,依赖于开放调用的类会具有更好的行为,并且比那些需要获得锁才能调用的方法相比,更容易与其
他的类合作。
避免和诊断死锁
1. 尝试定时的锁
可以使用每个显式的Lock类中定时的tryLock特性,来替代使用内部锁机制。
2. JVM可以使用线程转储来识别死锁。线程转储包括每个运行中线程的栈追踪信息,以及与之相似并随之发生的异常。
尽管死锁是遇到的最主要的活跃度危险,并发程序中仍然可能遇到一些其他的活跃度危险,包括:饥饿,丢失信号和活锁。
1. 饥饿
当线程访问它所需要的资源时却被永久拒绝,以至于不能再继续进行,这样就发生了饥饿。
但是要抵制使用线程优先级的诱惑,因为这会增加平台依赖性,并且可能引起活跃度问题。大多数并发应用程序可以对所有线程使用相同的优先级。
2. 弱响应性
不良的锁管理也可能引起弱响应性。
3. 活锁
活锁是线程中活跃度失败的另一种形式,尽管没有被阻塞,线程却依然不能继续,因为它不断重试相同的操作,却总是失败。
第11章 性能与可伸缩性
首先要保证程序是正确的,然后再让它更快-而后只有当性能需求和评估标准需要程序运行得更快时,才去进行改进。在设计并发应用程序的时候,最大
可能地改进性能,通常并不是最重要的事情。
尽管目标是希望全面提升性能,与单线程方法相比,使用多线程总会引入一些性能的开销。这些开销包括:与协调线程相关的开销(加锁、信
号、内存同步),增加的上下文切换,线程的创建和消亡,以及调度的开销。
3. 可伸缩性
可伸缩性指的是:当增加计算资源的时候(比如增加额外CPU数量、内存、存储器、I/O带宽),吞吐量和生产量能够相应地得以改进。
4. 对性能的权衡进行评估
避免不成熟的优化。首先使程序正确,然后再加快-如果它运行得还不够快。
线程引入的开销
1. 切换上下文
2. 内存同步
不要过分担心非竞争的同步带来的开销。基础的机制已经足够快了,在这个基础上,JVM能够进行额外的优化,大大减少或消除了开销。关注那些真正
发生了锁竞争的区域中性能的优化。
3. 阻塞
减少锁的竞争
1. 并发程序中,对可伸缩首要的威胁是独占的资源锁。
有3种方式来减少锁的竞争:
1. 减少持有锁的时间
2. 减少请求锁的频率
3. 或者用协调机制取代独占锁,从而允许更强的并发性。
2. 缩小锁的范围
3. 减少锁的粒度
减小持有锁的时间比例的另一种方式是让纯种减少调用它的频率(因此减少发生竞争的可能性)。这可以通过分拆锁和分离锁来实现,也就是采用相互独
立的锁,守卫多个独立的状态变量,在改变之前,它们都由一个锁守护的。这些技术减小了锁发生时的粒度,潜在实现了更好的可伸缩性-但是使用更多
的锁同样会增加死锁的风险。
监测CPU利用率
1. 不充足的负载
2. I/O限制
3. 外部限制
4. 锁竞争
向“对象池”说“不”
程序的可伸缩性是由必须连续执行的代码比例决定的。因为Java程序中串行化首要的来源是独占的资源锁,所以可伸缩下这些方式提升:减少用于获取
锁的时间,减小锁的粒度,减少锁的占用时间,或者用非独占或非阻塞锁来取代独占锁。
分享到:
相关推荐
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
《JAVA并发编程实践》既能够成为读者的理论支持,又可以作为构建可靠的、可伸缩的、可维护的并发程序的技术支持。《JAVA并发编程实践》并不仅仅提供并发API的清单及其机制,还提供了设计原则、模式和思想模型,使...
Java并发编程实践.pdf 本文档讲述了Java并发编程实践,特别是使用开源软件Amino构建并发应用程序。Amino是一个开源软件,具有可操作性、跨平台性、无锁数据结构等特点,适用于多核操作系统。下面是本文档的知识点...
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
Java 5以及6在开发并发程序取得了显著的进步,提高了Java虚拟机的性能,提高了并发类的可伸缩性,并加入了丰富的新并发构建块。在本书中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用,同时,还阐释...
并发编程是Java高级编程技能中的重要组成部分,尤其是在需要处理大量数据、提供快速响应、实现高吞吐量和高可伸缩性软件时显得尤为重要。 在Java并发编程中,多线程编程是指同时运行多个线程(Thread),每个线程...
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这 些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
《JAVA并发编程实践》并不仅仅提供并发API的清单及其机制,还提供了设计原则、模式和思想模型,使我们能够更好地构建正确的、性能良好的并发程序。《JAVA并发编程实践》适合于具有一定Java编程经验的程序员、希望...
Java 5以及6在开发并发程序中取得了显著的进步,提高了Java虚拟机的性能以及并发类的可伸缩性,并加入了丰富的新并发构建块。在《JAVA并发编程实践》中,这些便利工具的创造者不仅解释了它们究竟如何工作、如何使用...
第三部分聚焦于性能优化,讲解了如何避免活跃性问题(如死锁和活锁)以及如何提高并发代码的性能和可伸缩性。此外,还介绍了测试并发代码正确性和性能的实用技巧,这对于在生产环境中确保程序的稳定性和效率至关重要...
这本书全面地介绍了Java平台上的并发和多线程编程技术,旨在帮助开发者解决在实际工作中遇到的并发问题,提高程序的性能和可伸缩性。 并发编程是现代计算机系统中不可或缺的一部分,尤其是在多核处理器成为主流的...