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 statem开发者_如何转开发ents ?
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. 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.
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)
精彩评论