简体   繁体   中英

Why can't I synchronize instance block in java?

When I tried following

public class Test {

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

    public static void main(String [] args){

    }

}

isn't synchronizing instance block is just like synchronizing block of statements ?

Thanks, Bharat

While you can synchronized(this) in an instance initialiser block or in a constructor it is always always pointless as the object will not be shared at this stage. ie it is only accessible to one thread.

You can make an object available to more than one thread during the constructor, but this is generally considered a bad practice.

Why don't you synchronize inside:

public class Test {

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

    public static void main(String [] args){

    }

}

isn't synchronizing instance block is just like synchronizing block of statements ?

AFAIK, no, because it's not just a "block of statements" but an instance initializer. If you want the block execution to be synchronized, you can always synchronize on the this reference inside the initializer. Also, I don't think you can synchronize on top-level blocks (method blocks have a special syntactical support for this as you already know).

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

You are actually touching part of the language reasoning. It's said that constructors (which initializer block belongs to) not need to be synchronized because the are always called from a single thread. Another call would simply create another instance.

But since the constructor can actually leak resources to other instances it is allowed to use inner synchronized blocks to allow proper synchronization.

Because there is no this in a static initializer block.

That block gets executed when the class definition gets loaded, and not when an instance is created.

Its not necessary to synchronize within an static init block as loading classes is handled by the jvm before you get control.

In short, keep the block and remove synchronized(this)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM