为什么我不能在 java 中同步实例块?



当我尝试遵循时

public class Test {
    synchronized(this){   // compiler complains here
        System.out.println("instance block");
    }
    public static void main(String [] args){
    }
}

同步实例块不是和同步语句块一样吗?

谢谢,巴拉特

虽然您可以在实例初始化程序块或构造函数中synchronized(this),但它总是毫无意义的,因为在此阶段不会共享对象。即它只能由一个线程访问。

在构造函数期间,可以使一个对象对多个线程可用,但这通常被认为是一种糟糕的做法。

为什么不在内部同步:

public class Test {
    {
        synchronized(this) {
            System.out.println("instance block");
        }
    }
    public static void main(String [] args){
    }
}

同步实例块不是和同步语句块一样吗?

AFAIK,不,因为它不仅仅是一个"语句块",而是一个实例初始化器。如果希望同步块执行,则可以始终在初始化器内的this引用上同步。此外,我不认为您可以在顶级块上同步(方法块对此有特殊的语法支持,正如您所知)。

public class Test {
    // can't synchronize on a top-level block
    synchronized(this) {
    }
    {
        // OK
        synchronized(this) {
        }
    }
    // Methods have special syntactic support
    public synchronized void doIt() {
    }
    public void doIt() {
        // same as above
        synchronized(this) {
        }
    }
}

您实际上触及了语言推理的一部分。据说构造函数(初始化器块所属)不需要同步,因为总是从单个线程调用。另一个调用只会创建另一个实例。

但是,由于构造函数实际上可以将资源泄漏到其他实例,因此允许使用内部同步块来实现正确的同步。

因为在静态初始化程序块中没有这个。

该块在加载类定义时执行,而不是在创建实例时执行。

没有必要在静态init块内同步,因为在获得控制之前,加载类是由jvm处理的。

简而言之,保持块和删除同步(此)

最新更新