众所周知,Java 语言允许编译器重新排列已编译代码行,只要重新排序对代码语义没有影响即可。然而,编译器只需关心语义,如从当前线程。如果这种重新排序影响多线程情况下的语义,通常会导致并发问题(内存可见性)
我的问题:
通过允许编译器使用这个 freedm 可以实现什么目的?编译器真的有可能通过重新排列代码来生成更有效的代码吗?我还没有看到这方面的实际案例。我有时觉得这样做带来的并发风险远远超过了好处(如果有的话)。
程序员有什么方法可以告诉编译器不要像这样重新排列行吗?我知道使用同步原语可以有效地处理重新排列的副作用,但我问是否有任何直接的方法(编译器选项)来关闭它?
The javac
编译器几乎没有执行任何优化。
JIT 本机编译器可以在存在内存排序问题的情况下重新排序指令。然而,CPU 也可以重新排序指令和内存更新,这具有相同的效果。
通过允许编译器使用这个 freedm 可以实现什么目的?
主要好处是代码可移植性。您提供的保证越多,确保每个平台真正做到这一点就越困难。
通过允许 CPU 在可以执行指令时而不是严格按照指令执行指令,还可以显着提高性能。
编译器真的有可能通过重新排列代码来生成更有效的代码吗?
是的。但 CPU 进行的重新排序更为重要。
我还没有看到这方面的实际案例。我有时觉得这样做带来的并发风险远远超过了好处(如果有的话)。
程序员有什么方法可以告诉编译器不要像这样重新排列行吗?
这就是为什么你使用内存屏障,例如volatile
, synchronized
块和Lock
。当您使用这些时,您将获得线程安全保证。
我知道使用同步原语可以有效地处理重新排列的副作用,但我问是否有任何直接的方法(编译器选项)来关闭它?
您可以关闭 JIT,但大多数重新排序是由 CPU 完成的,因此不会有太大效果。
避免更新的重新排序只是线程安全问题的一小部分(它最大的问题是模糊且很少发生,这使得测试变得困难)并且一旦编写了线程安全代码,这个问题就会得到缓解。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)