private Object x = new Object();
public void doA() {
synchronized(x){
x = new Object();
//do something
}
}
public void doB() {
synchronized(x) {
//do something
}
}
假设
doA()
和 doB()
被同时调用,但 doA()
首先进行。所以 B 将被阻塞,直到 doA()
完成即使
doA()
在 x = new x
调用中修改 x 也是如此吗?或者在 x = new x
中的这一行 doA()
之后 doB()
将不再被阻止,因为 x
已更改? 最佳答案
会发生什么实际上取决于 doA()
运行的速度:
如果 doA()
在 x
到达其同步块(synchronized block)之前更改了 doB()
的值,则 doB()
将锁定 doA()
创建的 新 对象。
如果 doB()
速度很快并且 synchronized(x)
部分在 doA()
可以更改 x
的值之前被评估,那么 doB()
将不得不等到 doA()
的 synchronized
块完成。
解释
每当 Java 在任一方法中获取 synchronized(x)
代码时,它都会评估变量 x
,并且该变量为 Java 提供一个对象。所以 Java 然后尝试锁定该对象,并保持锁定在该对象上。或者,如果该对象上已有锁,它将等待锁消失。 (每当 Java 到达 synchronized(x)
代码时,它都会获取变量的值并忽略变量本身,因此您可以在之后随意更改变量,但锁定和锁定检查仍然发生在变量的先前值上。)
关于如果更改,Java 会同步阻塞吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56281291/