在某些链接中,给出了同步块(synchronized block)内的代码重新排序是可能的,而其他一些站点则告诉这是不可能的。您能否举个例子来描述使用synchronized时代码重新排序实际发生的情况?
最佳答案
有两种可能的重新排序:
- 同步块(synchronized block)之前或之后的语句可以移动到同步块(synchronized block)内部(当然前提是它们不在不同的同步块(synchronized block)中) - 有时称为 the "roach motel" principle
- 只要修改顺序一致,同步块(synchronized block)内的语句就可以重新排序(即,从与该 block 共享先发生关系的其他代码中看不到效果)
但更重要的是:如果您的代码正确同步,这些重新排序不会影响程序的执行,这是您应该关心的。
示例(所有变量最初为 0):
主题1:
a=1;
synchronized(lock) {
b=1;
c=1;
}
d=1;
线程2:
synchronized(lock) {
if (a==1) print(b); // can print 0 or 1
if (b==1) print(a)/print(c); // always prints 1
if (b==1) print(d); // can print 0 or 1
if (d==1) print(a)/print(b)/print(c); // always prints 1
}
特别是,将 d=1
移至 c=1
之前或将 a=1
移至 b=1
是允许的,因为线程 2 无法观察到它,因为线程 1 执行的同步块(synchronized block)看起来像线程 2 的原子操作。
另一方面,不使用相同锁的线程将能够观察到这些重新排序。
关于java - java中的同步和代码重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18929518/