18

Why is starting a new thread in a constructor frowned upon in Java (or anywhere, for that matter). I'm getting warnings from Netbeans for doing so, but it isn't giving me any refactoring suggestions. I'm writing a client/server Swing application, and the thread I'm starting is in the server's JFrame constructor, in order to continuously listen for client datagrams.

Why is this not good practice and how should I avoid it?

Richard Stokes
  • 3,532
  • 7
  • 41
  • 57

3 Answers3

27

Starting a thread from the constructor lets the started thread access the object being constructed before it's properly constructed, and thus makes a not completely constructed object available to the new thread.

You could create the thread in the constructor, and provide a "startup" method to start the thread from the outside.

Or you could make the constructor and startup methods private and provide a static factory method which would create the object, start the thread, and return the created object.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    I think JB's solution is the best. Where you make the constructor unavailable by making it private, and provide a static factory method called createSomething, which new's the class, and then calls an (also) private init method on it, which in turn creates and possibly starts the thread. – Mike Nov 08 '11 at 22:11
  • 1
    not to mention that it makes the class that contains the constructor a nightmare to unit test – matt b Nov 09 '11 at 02:42
  • What if starting the thread is the last line of the constructor, and all instance variable assignments have occurred? Is there still no safety guarantee there? – Evan LaHurd Oct 06 '15 at 17:47
  • Interestingly enough, java's own java.util.Timer creates and starts a thread from its constructor. – pulse0ne Nov 21 '16 at 16:05
  • @JackmeriusTacktheritrix Correct, there is no safety guarantee even if it is the last line of the constructor. For instance, if someone were to subclass the class in question: http://stackoverflow.com/a/10758741/4580653 – pulse0ne Nov 21 '16 at 16:08
1

Have a look at this link http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html#code4

This is do with implicit references to this and subclassing.

Ravi Bhatt
  • 3,147
  • 19
  • 21
  • The answer is correct, but you didn't give the *actual answer*. Quoting the reason from that IBM article: "Don't start threads from within constructors" should help. – zengr Nov 08 '11 at 22:02
0

Making the class final, also could be a solution, because there will be no subclasses.

omilus
  • 1,176
  • 11
  • 9