Kabeer
Kabeer

Reputation: 69

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

Upvotes: 0

Views: 289

Answers (5)

M Platvoet
M Platvoet

Reputation: 1654

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.

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533670

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. i.e. 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.

Upvotes: 2

extraneon
extraneon

Reputation: 23960

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)

Upvotes: 0

Sanjay T. Sharma
Sanjay T. Sharma

Reputation: 23218

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

Upvotes: 1

Petar Ivanov
Petar Ivanov

Reputation: 93050

Why don't you synchronize inside:

public class Test {

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

    public static void main(String [] args){

    }

}

Upvotes: 1

Related Questions