If the ThreadGroup passed to Thread construction is null, the group of currentThread() will be used. Anyway, you can not create a thread which no group associates with. That’s the current implementation from SUN.
All well and good, but it’s not explicitly mentioned either in the JDK docs or in the JVM specification, and that’s the problem - it’s not a declared behaviour so it leads to unexpected results.
Cas
Yeah, I can read ::), but where does it say that a default threadgroup is created by the JVM on startup and the main thread is assigned to it? Not in the JVM specs it doesn’t. It still looks ambiguously defined; it’s hinted at here and there but never explicit. And as we’ve noted, the side effects are quite serious, leading to a VM crash or OS resource starvation.
Cas
Well, API-docs never tell you everything, but in my experience I have seen worse API-docs than the one of the JDK. If you just look a little further you can find it in the Java-Tutorial:
http://java.sun.com/docs/books/tutorial/essential/threads/group.html
`Every Java thread is a member of a thread group. Thread groups provide a mechanism for collecting multiple threads into a single object and manipulating those threads all at once, rather than individually. For example, you can start or suspend all the threads within a group with a single method call. Java thread groups are implemented by the ThreadGroup(in the API reference documentation) class in the java.lang package.
The runtime system puts a thread into a thread group during thread construction. When you create a thread, you can either allow the runtime system to put the new thread in some reasonable default group or you can explicitly set the new thread’s group. The thread is a permanent member of whatever thread group it joins upon its creation–you cannot move a thread to a new group after the thread has been created. `
[quote]but where does it say that a default threadgroup is created by the JVM on startup and the main thread is assigned to it?
[/quote]
On the same page as my previous links
[quote]When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class).
[/quote]
That, combined with the knowledge quoted above that every thread is assigned a threadgroup, should pretty much close this case.
Someone posted code showing that a bunch of Threads that were created but weren’t executed would cause a memory error, even if their references were lost. I will take a look, but I bet that they weren’t garbage collected since they were in the default threadgroup, and thus it would still be possible to execute them.
That’s exactly it. Started without a group they are put into the default ThreadGroup. It is still possible to start them by running Thread.getCurrentThread().getThreadGroup() then enumerating through the threads in the group to start it. Basically it still has a reference to the Thread in the default threadgroup so it is never garbage collected.
It is the way it is supposed to work, but it is very misleading… not well documented… and can cause headaches (don’t I know it!). Basically just a “gotcha” when using the invokeXXX() functions.
Aye, that’s what I was getting at. When you look at it in the wider context of JVM stability, and the even wider one of system stability, you’d be wondering why it isn’t dealt with a bit more specifically…
Cas
it is??
last time I looked, ThreadGroup only has methods for getting active Threads, not inactive unstarted Threads
(and there is a sun bug report already highlighting this flaw)
p.s.
While trauling the bug database, I was suprised to see the number of confirmed bugs in Thread, that Sun have acknowledged, but arn’t about to fix. (something about a fundamental api flaw… ;))