文档详情

Java并发编程实践-教程-05章.pdf

发布:2019-06-26约4.92万字共33页下载文档
文本预览下载声明
第 1 页 共 32 页 第5章 数据冲突及诊断工具MTRAT 第 5 章 数据冲突及诊断工具MTRAT1 5.1 如何避免数据冲突2 5.1.1 数据冲突与竞争条件2 5.1.2 锁与数据冲突4 5.1.3 采用原子性操作避免数据冲突9 5.1.4 采用Volatile避免数据冲突11 5.1.5ThreadLocal 14 5.2 使用阻塞队列的生产者-消费者模式15 5.3 MTRAT介绍19 5.3.1 有潜在数据冲突的例子20 5.3.2 MTRAT软件介绍22 5.3.3 Mtrat软件测试案例25 5.3.4 Mtrat软件的其他选项27 5.4 使用MTRAT诊断数据冲突28 参考文献:32 Linux公社(LinuxIDC.com) 是包括Ubuntu,Fedora,SUSE技术,最新IT资讯等Linux专业类网站。 第 2 页 共 32 页 在前面的章节中,我们已经了解了线程安全和数据冲突的概念,在本章中我们将讲解 如何避免数据冲突,以及如何进行诊断。由于并行程序的不确定性造成并行程序的错误很难 查找,重现和调试,IBM 提供的 MTRAT 工具 可以收集程序的运行时信息,实时分析程序 中所有可能的并行程序错误(如死锁、数据冲突) 。 5.1 如何避免数据冲突 在前面的章节中我们已经了解了数据冲突。当线程之间共享数据引起了并发执行程序 中的同步问题就是数据冲突。 Java 的数据有两种基本类型内存分配模式(不算虚拟机内部类型,详细内容参见虚拟 机规范):运行时栈和堆两种。由于运行时栈是线程所私有的,它主要用来保存局部变量和 中间运算结果,因此它们的数据是不可能被线程之间所共享的。内存堆是创建类对象和数组 地方,它们是被虚拟机内各个线程所共享的,因此如果一个线程能获得某个堆对象的引用, 那么就称这个对象是对该线程可见的。 编写线程安全的代码,本质上就是管理对状态(state )的访问,而且通常这些状态都是 共享的、可变的。一个对象的状态就是它的数据,存储在状态变量(state variables )中,比 如实例域或静态域。对象的状态还包括了其他附属对象的域。 例如,在 Web 网站中,我们为统计系统的点击数设计了一个计数器。由于计数器是被 多用户共享的,每个用户访问时都涉及“读-改-写”等操作,由于这些操作都不是原子的, 计数器有可能出现问题。 两个线程在缺乏同步的条件下,试图同时更新一个计数器时。假设计数器的初始值为 19,在某些特殊的分时里,每个线程都将读它的值,并看到值是 19,然后同时加 1,最后 都将 counter 设置为 20。很显然,这不是我们期望发生的事情:一次递增操作凭空取消了, 一次命中计数被永久地取消了。在基于 Web 的服务中,如果计数器出现这种问题,可能问 题不大,但已经导致严重的数据完整性问题和错误。如各在其他环境中,如银行帐号管理, 那就不可原谅。 在并发编程环境中,这种问题有一个专用的名称叫竞争条件。 5.1.1
显示全部
相似文档