Java: Starting a New Thread in a Constructor

Why not to start a thread in the constructor? How to terminate?

To your first question: Starting a thread in a constructor passing in this escapes this. That means that you are actually giving out a reference to your object before it is fully constructed. The thread will start before your constructor finishes. This can result in all kinds of weird behaviors.

To your second question: There is no acceptable way to force another thread to stop in Java, so you would use a variable which the thread would check to know whether or not it should stop. The other thread would set it to indicate that the first thread would stop. The variable has to be volatile or all accesses synchronized to ensure proper publication. Here is some code which would be something like what you want.

public class MyNewThread implements Runnable {

private final Thread t;
private volatile boolean shouldStop = false;

MyNewThread() {
t = new Thread (this, "Data Thread");
}

public void start() {
t.start();
}

public void stop() {
shouldStop = true;
}

public void run() {
while(!shouldStop)
{
// do stuff
}
}
}

Whatever wants to create and start the thread would do:

MyNewThread thread = new MyNewThread();
thread.start();

Whatever wants to stop the thread would do:

thread.stop();

Java: starting a new thread in a constructor

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.

Starting Thread from inside it's constructor

As noted in my comment, it's bad practice to extend Thread, and so the question is a non-issue. But again your suggested code is much more than "bad practice" -- it's dangerous. You're performing critical actions on an object before it has been fully constructed, and this can lead to unforeseen and difficult to debug bugs and side effects. Also this greatly limits the flexibility of your code, since now you are forced to use the thread in one and only one way.

Regarding the separate issue of implementing Runnable or extending Thread, this has been well discussed on this site in multiple threads including this one, and I invite you to take a look.

Why it is bad practice to create a new thread on constructors?

Why it is bad practice to create a new thread on constructors?

Findbugs is alerting you to the problem with instruction reordering possibilities around object construction. Although the memory space for a new object is allocated, there is no guarantee that any of the fields have been initialized by the time your InnerThread has been started. Although the final fields will be initialized before the constructor finishes, there is no guarantee that if InnerThread starts to use (for example) aField when it starts, that it will be initialized. The Java compiler does this for performance reasons. It also has the option to move the initialization of non-final fields to after the new instance has been returned by the constructor.

If you start a new thread in the constructor then there is a chance that the thread will be dealing with a partially initialized object. Even if the thread.start() is the last statement in your constructor, the new thread may be accessing a partially constructed object because of the reordering. This is part of the Java language specification.

Here's a good link about the topic: calling thread.start() within its own constructor

It mentions the following:

By starting it from within the constructor, you are guaranteed to violate the Java Memory Model guidelines. See Brian Goetz's Safe Construction Techniques for more info.

Edit:

Since you code is starting a new thread that is accessing afield, according to the Java Memory Model there is no guarantee that afield will be properly initialized when the thread starts to run.

What I would recommend instead is to add a start() method on your class that calls the thread.start(). This is a better practice and makes it more visible to other classes that are using this class that a thread is created in the constructor.

calling new thread inside is constructor

IMHO, do not do this. You're allowing the this reference to escape during construction.

Can I launch a thread from a constructor?

Well, unless you particularly want to disagree with Brian Goetz on a Java concurrency issue, I'd assume it's wrong. Although his exact words are "is best not to...", I'd still heed his advice. From JCIP, p. 42:

"A common mistake that can let the
'this' reference escape during
construction is to start a thread
from a constructor
[...] There's
nothing wrong with creating a thread
in a constructor, but it is best not
to start the thread immediately.
Instead, expose a start or initialize
method..."

Update: just to elaborate on why this is a problem. Although there's guaranteed to be a memory barrier between the call to Thread.start() and that thread's run() method actually beginning to execute, there's no such barrier between what happens during the constructor after the call to Thread.start(). So if some other variables are still to be set, or if the JVM carries out some "have-just-constructed-object" housekeeping, neither of these are guaranteed to be seen by the other thread: i.e. the object could be seen by the other thread in an incomplete state.

Incidentally, aside from whether or not it actually breaks the JMM, it also just feels a bit like an "odd thing to do" in a constructor.

Why shouldn't I use Thread.start() in the constructor of my class?

But the object has been fully constructed, the constructor has nothing left to do but return

Yes and no. The problem is that according to the Java memory model, the compiler is able to reorder the constructor operations and actually finish the constructor of the object after the constructor finishes. volatile or final fields will be guaranteed to be initialized before the constructor finishes but there is no guarantee that (for example) your ImportantData data field will be properly initialized by the time the constructor finishes.

However as @meriton pointed out in comments, there is a happens before relationship with a thread and the thread that started it. In the case of #2, you are fine because data has to be assigned fully before the thread is started. This is guaranteed according to the Java memory model.

That said, it is considered bad practice to "leak" a reference to an object in its constructor to another thread because if any constructor lines were added after the t.start() it would be a race condition if the thread would see the object full constructed or not.

Here's some more reading:

  • Here's a good question to read: calling thread.start() within its own constructor
  • Doug Lea's memory model page talks about instruction reordering and constructors.
  • Here's a great piece about safe constructor practices which talks about this more.
  • This is the reason why there are problems with the "double check locking" problem as well.
  • My answer to this question is relevant: Is this a safe publication of object?


Related Topics



Leave a reply



Submit