有没有办法确保在doB之前执行doA?我想到的一件事是将每个语句包装在同步块中。
object1.doA();
object2.doB();
对volatile变量的方法调用是否作为volatile写入?
编辑 - 我真正需要的是让其他线程在doB之前看到doA的效果。
答案 0 :(得分:2)
这些语句不会从执行该段代码的线程的角度重新排序(它们可能在实践中重新排序,但只有当重新排序从该线程的角度来看没有效果时)。
然而,在看到doB
的结果之前,另一个主题可能会看到doA
的结果。如果这是一个问题,您应该锁定代码以使其成为原子,例如使用synchronized
块。
请注意,使用两个synchronized
块并没有太大成效 - 特别是JVM很可能会将它们合并为一个(假设它们使用相同的监视器,但如果它们没有,那么你赢了不一定能实现原子性。
答案 1 :(得分:2)
这完全取决于您观察来自doA()
和doB()
的来电效果的位置。
如果您观察到与执行调用相同的线程的影响,那么您可以保证看到它们没有重新排序。不允许重新排序来更改单线程行为。如果写的代码表示在doA()
之前调用了doB()
,那么这就是线程将要观察的内容......如果它正在查找。简而言之,没什么惊喜。
如果您观察到来自不同线程的影响,则保证该线程能够观察到与同步点处的单线程情况一致的状态。但是,如果一个线程试图观察另一个线程的动作而没有正确的同步,那么它可以观察重新排序的效果。
所以......
如何防止JVM重新排序语句
实际上,我认为你不能。但是,如果您正确编写(多线程)应用程序,它将无法观察重新排序的影响。如果它无法观察到效果,如果有或没有重新排序,它对行为没有任何影响。
对volatile变量的方法调用是否充当易失性写入?
没有
调用本身没有特定的同步行为,但它们之前是易失性读取(自然)。
...我真正需要的是让其他线程在doB之前看到doA的效果。
然后必须编写代码,以便在访问由相应调用更改的状态时进行适当的同步。从技术上讲,需要在一个线程上的写入与其他线程上的后续读取之间进行适当的“先发生”排序...对于受方法调用影响的所有状态。
没有魔力。没有捷径。只是正确写同步。