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/

10-11 03:55