同步语句是否可以被 Java 编译器重新排序以进行优化?

Amb*_*ber 1 java multithreading

同步语句可以重新排序吗?即:可以:

synchronized(A) {
   synchronized(B) {
     ......
   }
}
Run Code Online (Sandbox Code Playgroud)

变得 :

synchronized(B) { 
    synchronized(A) { 
     ...... 
     }  
}
Run Code Online (Sandbox Code Playgroud)

Gra*_*ray 5

同步语句可以重新排序吗?

我假设您是在问编译器是否可以重新排序 synchronized块以便锁定顺序与代码的顺序不同。

答案是不。一个synchronized块(和volatile字段访问)征收订购编译器的限制。在您的情况下,您不能在另一个监视器进入之前移动监视器输入,也不能在另一个监视器退出之后移动监视器退出。请参阅下面的网格。

引用JSR 133(Java 内存模型)常见问题解答

例如,编译器不可能在获取之前或发布之后移动您的代码。当我们说获取和释放作用于缓存时,我们使用速记来表示许多可能的效果。

Doug Lea 的JSR-133 Cookbook有一个网格,显示了重新排序的可能性。网格中的空白条目表示允许重新排序。在您的情况下,输入synchronized块是“MonitorEnter”(与加载volatile字段相同的重新排序限制),退出synchronized块是“MonitorExit”(与存储到volatile字段相同)。

在此处输入图片说明