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

时间:2011-06-19 06:00:55

标签: java multithreading synchronization

当我尝试按照

public class Test {

    synchronized(this){   // compiler complains here
        System.out.println("instance block");
    }

    public static void main(String [] args){

    }

}

不同步实例块就像同步语句块一样吗?

谢谢, 巴勒特

5 个答案:

答案 0 :(得分:2)

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

你可以在构造函数中使一个对象可用于多个线程,但这通常被认为是一种不好的做法。

答案 1 :(得分:1)

为什么不在里面同步:

public class Test {

    {
        synchronized(this) {
            System.out.println("instance block");
        }
    }

    public static void main(String [] args){

    }

}

答案 2 :(得分:1)

  

不同步实例块就像同步语句块一样吗?

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) {
        }
    }
}

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

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

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

没有必要在静态init块中进行同步,因为在获得控制权之前,jvm会处理加载类。

简而言之,保持阻止并删除synchronized(this)