内存屏障与JVM并发 - 编程入门网
内存屏障与JVM并发时间:2011-09-04 infoq 崔康译内存屏障,又称内存栅栏,是一组处理器指令,用于实现对内存操作的顺序限 制。本文介绍了内存屏障对多线程程序的影响。我们将研究内存屏障与JVM并发机 制的关系,如易变量(volatile)、同步(synchronized)和原子条件式 (atomic conditional)。本文假定读者已经充分掌握了相关概念和Java内存模 型,不讨论并发互斥、并行机制和原子性。内存屏障用来实现并发编程中称为可 见性(visibility)的同样重要的作用。 内存屏障为何重要? 对主存的一次访问一般花费硬件的数百次时钟周期。处理器通过缓存 (caching)能够从数量级上降低内存延迟的成本这些缓存为了性能重新排列待定 内存操作的顺序。也就是说,程序的读写操作不一定会按照它要求处理器的顺序 执行。当数据是不可变的,同时/或者数据限制在线程范围内,这些优化是无害的 。如果把这些优化与对称多处理(symmetric multi-processing)和共享可变状 态(shared mutable state)结合,那么就是一场噩梦。当基于共享可变状态的 内存操作被重新排序时,程序可能行为不定。一个线程写入的数据可能被其他线 程可见,原因是数据写入的顺序不一致。适当的放置内存屏障通过强制处理器顺 序执行待定的内存操作来避免这个问题。 内存屏障的协调作用 内存屏障不直接由JVM暴露,相反它们被JVM插入到指令序列中以维持语言层并 发原语的语义。我们研究几个简单Java程序的源代码和汇编指令。首先快速 看一 下Dekker算法中的内存屏障。该算法利用volatile变量协调两个线程之间的共享 资源访问。 请不要关注该算法的出色细节。哪些部分是相关的?每个线程通过发信号试图 进入代码第一行的关键区域。如果线程在第三行意识到冲突(两个线程都要访问 ),通 过turn变量的操作来解决。在任何时刻只有一个线程可以访问关键区域。
内存屏障与JVM并发(2)时间:2011-09-04 infoq 崔康译硬件优化可以在没有内存屏障的情况下打乱这段代码,即使编译器按照程序员 的想法顺序列出所有的内存操作。考虑第三、四行的两次顺序volatile 读操作。 每一个线程检查其他线程是否发信号想进入关键区域,然后检查轮到谁操作了。 考虑第12、13行的两次顺序写操作。每一个线程把访问权释放给其他线程,然后 撤销自己访问关键区域的意图。读线程应该从不期望在其他线程撤销访问意愿后 观察到其他线程对turn变量的写操作。这是个灾难。但是如果这些变量没有 volatile修饰符,这的确会发生!例如,没有volatile修饰符,第二个线程在第 一个线程对turn执行写操作(倒数第二行)之前可能会观察到第一个线程对 intentFirst(倒数第一行)的写操作。关键词volatile避免了这种情况,因为它在 对turn变量的写操作和对 intentFirst变量的写操作 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |