5

Kind of a follow up question to Why can't Java constructors be synchronized?: if an object's constructor can't be synchronized, does that mean it's impossible to create two instances at literally the same time? For instance:

public class OutgoingMessage {
    public OutgoingMessage() {
        this.creationTime = new Date();
    }
    Date creationTime;
}

Would creationDate.getTime() always return a different value? I'm aware of the basics of multitasking/multithreading but what about multiple CPU cores? In that case the operating system doesn't have to switch contexts or am I wrong here?

Community
  • 1
  • 1
Miro Kropacek
  • 2,742
  • 4
  • 26
  • 41
  • Did you mean `creationTime.getDate()`? – RaGe Apr 23 '15 at 16:48
  • Even ignoring multicore `creationTime` could still be the same for two objects. – Dave Newton Apr 23 '15 at 16:48
  • 3
    the fact that the object is not visible to other threads until it is constructed does not mean that 2 objects cannot be constructed simulatneously – njzk2 Apr 23 '15 at 16:48
  • @BretC: what was wrong with your comment? I liked it because what I want to achieve is to have an unique value of creationTime and your idea fits into that very nicely. – Miro Kropacek Apr 23 '15 at 17:02
  • 1
    @MiroKropacek Use a synchronized static method in a utility class. I'm not convinced you really *want* to do this, but without knowing what you're using the value for it's hard to say. – Dave Newton Apr 23 '15 at 17:07
  • @DaveNewton that's actually a good idea. I was looking at http://stackoverflow.com/questions/12252967/how-to-make-java-util-date-thread-safe and thinking whether it applies to constructors, too. – Miro Kropacek Apr 23 '15 at 17:16
  • 1
    I smell an XY problem here; that is, you are asking question X, but X is not necessarily on the best path to solve your real problem, Y. Why do you _care_ whether two objects can be created "at the same time"? Is it that you don't want two objects to have the same `creationTime`? In that case, write a static method getCreationTimeForNewMessage() that is guaranteed never to return the same timestamp more than once, and call that method from your constructor. Or, if not, then what _is_ the real problem? – Solomon Slow Apr 23 '15 at 17:33
  • @MiroKropacek I thought I'd got the wrong end of the stick. I'll add it as an answer... – BretC Apr 23 '15 at 19:00

2 Answers2

7

if an object's constructor can't be synchronized, does that mean it's impossible to create two instances at literally the same time?

No. As the answers in the other question state, a constructor can't be synchronized simply because nothing exists to synchronize on before the constructor is called. You could do something like this:

public OutgoingMessage(){
   synchronized(this){
      //synchronized constructor
   }
}

But then the question becomes: how on earth would two threads access the same constructor of the same instance at the same time? They couldn't, by the very definition of how constructors work. That's why you can't synchronize on a constructor- because it doesn't make any sense.

That is not saying that two instances of a class can't be constructed at the same time.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Oh-oh, that's what I was afraid about. Would a private static lock object work for this purpose? – Miro Kropacek Apr 23 '15 at 17:04
  • @MiroKropacek It really depends on exactly what you're trying to do, but sure, you could synchronize on a static lock Object to restrict parts of your constructor to a single Thread. You might also take BretC's example of synchronizing on the class itself. – Kevin Workman Apr 23 '15 at 17:06
1

If you want to make sure that the block of code inside your constructor is never executed by more than one thread at the same time, you can synchronise on the Class, for example...

public class MyClass {
    public MyClass() {
        synchronized(MyClass.class) {
            // Thread unsafe code here!
        }
    }
}

You don't have to use "MyClass.class" if you don't want to, you could have a "LOCK" object, for example...

public class MyClass {
    private static final Object LOCK = new Object();

    public MyClass() {
        synchronized(LOCK) {
            // Thread unsafe code here!
        }
    }
}
BretC
  • 4,141
  • 13
  • 22