有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java同步块与私有不可变对象和同步方法的差异

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.

但我不能完全理解这一点。一个恶意用户怎么能永远持有一把锁?任何人都可以用一个示例代码来解释上述场景吗


共 (2) 个答案

  1. # 1 楼答案

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

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

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

    这可能会得到意外的结果,例如,在执行otherMethod时导致getCount阻塞

    在第一种方法中,由于监视器锁lockObject是私有的,其他类无法直接访问它,因此它比第二种方法更受欢迎

  2. # 2 楼答案

    简单地说:

    当你在方法级别使用锁时,你会得到一个完整类的对象的锁,在这个类中你有一个同步的方法

    假设有任何用户提供了一些闪亮的代码来执行方法,直到宇宙结束。。这将导致其他线程因使用类中的其他方法而被阻止

    这就是监视器对象和同步块是首选方式的原因