According to the Java Language Specification, constructors cannot be marked synchronized because other threads cannot see the object being created until the thread creating it has finished it. This seems a bit odd, because I can indeed have another thread view the object while it's being constructed:
public class Test { public Test() { final Test me = this; new Thread() { @Override public void run() { // ... Reference 'me,' the object being constructed } }.start(); } }
I know that this is a pretty contrived example, but it seems in theory that someone could come up with a more realistic case where marking the constructor synchronized would be legitimate in order to prevent races with threads like this one.
My question is this: is there a reason that Java would specifically disallow the synchronized modifier on a constructor? Perhaps my above example is flawed, or perhaps there really is no reason and it's an arbitrary design decision. In either case, I'm really curious and would love to know the answer.
No, a constructor cannot be synchronized in Java. The JVM ensures that only one thread can invoke a constructor call at a given point in time. That is why no need to declare a constructor as synchronized and it is illegal in Java.
No, constructor cannot be synchronized. Because constructor is used for instantiating object, when we are in constructor object is under creation. So, until object is not instantiated it does not need any synchronization. Any attempt to do so is against java coding syntax.
Synchronization can result in hold-wait deadlock where two threads each have the lock of an object, and are trying to acquire the lock of the other thread's object. Synchronization must also be global for a class, and an easy mistake to make is to forget to synchronize a method.
In simple two lines Disadvantage of synchronized methods in Java : Increase the waiting time of the thread. Create performance problem.
If you really need synchronization of the rest of the constructor versus any threads which anyhow gets a reference to your not-yet-totally-constructed object, you can use a synchronized-block:
public class Test { public Test() { final Test me = this; synchronized(this) { new Thread() { @Override public void run() { // ... Reference 'me,' the object being constructed synchronized(me) { // do something dangerous with 'me'. } } }.start(); // do something dangerous with this } } }
Usually it is considered bad style to "give out" your not-yet-constructed object like this, so a synchronized constructor is not necessary.
In some corner cases a synchronized constructor would be useful. Here is a more realistic example, from the discussion of Bozho's answer:
public abstract class SuperClass { public SuperClass() { new Thread("evil") { public void run() { doSomethingDangerous(); }}).start(); try { Thread.sleep(5000); } catch(InterruptedException ex) { /* ignore */ } } public abstract void doSomethingDangerous(); } public class SubClass extends SuperClass { int number; public SubClass () { super(); number = 2; } public synchronized void doSomethingDangerous() { if(number == 2) { System.out.println("everything OK"); } else { System.out.println("we have a problem."); } } }
We want that the doSomethingDangerous()
method is only called after construction of our SubClass object is complete, e.g. we only want the "everything OK" output. But in this case, when you only can edit your SubClass, you have no chance of achieving this. If the constructor could be synchronized, it would solve the problem.
So, what we learn about this: never do something like I did here in the superclass constructor, if your class is not final - and don't call any non-final methods of your own class from your constructor.
The question has been raised on a discussion list used by the writers of the Java concurrent API and the Java Memory Model. Several answers were given, in particular Hans Boehm replied:
Some of us (myself included IIRC) actually argued during the Java memory model deliberations that synchronized constructors should be allowed. Now I could go either way on it. Client code shouldn't use races to communicate the reference, so it shouldn't matter. But if you don't trust the clients of [your class], I think synchronized constructors could possibly be useful. And that was much of the reasoning behind final field semantics. [...] As David said, you can use synchronized blocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With