27

I was asked this question in an interview today.

"When we create a thread with pthread_create() (POSIX Threads), the thread starts on its own. Why do we need to explicitly call start() in Java. What is the reason that Java doesnt start the thread when we create an instance of it."

I was blank and interviewer was short of time and eventually he couldn't explain the reason to me.

slm
  • 15,396
  • 12
  • 109
  • 124
Chander Shivdasani
  • 9,878
  • 20
  • 76
  • 107

2 Answers2

23

In Java not starting the thread right away leads to a better API. You can set properties on the thread (daemon, priority) without having to set all the properties in the constructor.

If the thread started right away, it would need a constructor,

public Thread(Runnable target, String name, ThreadGroup threadGroup, int priority, boolean daemon, ContextClassLoader contextClassLoader, long stackSize)

To allow setting all these parameters before the thread started. The daemon property can't be set after the thread has started.

I'm guessing that the POSIX API takes a struct with all the thread properties in the call to pthread_create(), so it makes sense to start the thread right away.

sbridges
  • 24,960
  • 4
  • 64
  • 71
  • 5
    The posix API does indeed take a struct containing all the thread properties. The struct in question is a pthread_attr_t. As to which approach is better, I can't take a side. It's highly dependent on what you're comfortable with. Neither has any real technical benefits over another, it's just how the API is exposed. – Varun Madiath Mar 11 '11 at 07:07
  • 1
    *Since none of these parameters can be changed once the thread has started.* `Name` sure can at any time. it's kept in the java heap and has no representation in the native OS part. The classloader (ccl), however, is Changed A LOT during execution and changing is its prime goal. Priority can be altered as well. Daemon can be changed at any time as well. – bestsss Mar 11 '11 at 07:12
  • @bestsss: [`setDaemon()`](http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)) "must be called before the thread is started.". – Joachim Sauer Mar 11 '11 at 07:16
  • 1
    @Varun: in that case creating the `struct` is in fact the same as creating the `Thread` object. Populating its fields is done in a similar way in Java (using setters instead of direct field access) and calling `pthread_create` is equivalent to calling `start()` then. The two APIs are more similar than they seem at first glance, then. – Joachim Sauer Mar 11 '11 at 07:17
  • @Joachim, this is true, daemon can be changed only before start, and after death – bestsss Mar 11 '11 at 07:19
  • @bestsss: why after death? Nothing in the doc suggests this is possible and it would have no effect anyway. – Joachim Sauer Mar 11 '11 at 07:23
  • @Joachim, about no effect after death - of course, actually at 1st I was thinking that daemon is inherited by the currentThread and then got mixed up, that the currentThread cannot have it changed any more; `IllegalThreadStateException if this thread is active.` . *Active*, after it's dead, it's not active any more. – bestsss Mar 11 '11 at 07:27
  • Thread.setContextClassLoader(...) can be any number of times (even while thread is running); – Santhosh Kumar Tekuri Mar 11 '11 at 13:13
5

The reasons are a lot. But I'll give you a few:

  • The thread, itself, might start executing before returning the instance.
  • The context classloader MUST be set properly before running the thread (look at the previous point)
  • Extra configuration like priority should be set before starting the thread
  • pthreads uses a pointer to the initialized structure(s), since the java.lang.Thread cannot be properly initialized in the end of the c-tor, see points above; straight call to the native pthread_create to actually execute the code makes no sense

I hope you get the idea.

slm
  • 15,396
  • 12
  • 109
  • 124
bestsss
  • 11,796
  • 3
  • 53
  • 63