java - 私有(private)不可变对象(immutable对象)的同步块(synchronized block)和同步方法的区别

标签 java multithreading synchronization

private final Object lockObject = new Object();
public void getCount() {
    synchronized( lockObject ) {
        ...
    }
}

为什么上面的代码比下面的代码更好:

public void synchronized getCount() {
      ...
}

我搜索并找到了如下所述的解释。

Putting it on the method means you are using the lock of the object itself to provide thread safety. With this kind of mechanism, it is possible for a malicious user of your code to also obtain the lock on your object, and hold it forever, effectively blocking other threads. A non-malicious user can effectively do the same thing inadvertently.

但我无法完全理解这一点。恶意用户如何能够永远持有锁?任何人都可以用示例代码进行解释,以证明上述情况的合理性吗?

最佳答案

public class Example {
    public void synchronized getCount() {
            ...
    }
}

它正在同步当前对象this。其他类能够获取当前对象的引用并将其用作监视器锁:

public class OtherClass {

    public void otherMethod() {
        Example example = new Example();
        synchronized (example) {
            ...
        }
    }
}

这可能会得到意想不到的结果,例如,导致 getCount 在执行 otherMethod 时被阻止。

使用第一种方法,由于监视器锁 lockObject 是私有(private)的,其他类无法直接访问它,因此优于第二种方法。

关于java - 私有(private)不可变对象(immutable对象)的同步块(synchronized block)和同步方法的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51007407/

相关文章:

c++ - Win32 重置事件,如带有 boost C++ 的同步类

interface - FPGA 上的输入信号边沿检测

java - 获取连接返回的行数超出应有的行数

java - 为 DAO 编写测试

java - 从外部类和线程调用Jframe中的方法来设置标签值

python - Pool.map 挂起——如何进行异常处理

c++ - 互斥体解锁时解除定时接收阻止

java - 在测试中用 ExecutorService 替换 ManagedExecutorService

java - 在 Java 中为链中的变量赋值

c++ - 如果我从不同的线程调用一个对象成员函数会发生什么?