views:

77

answers:

1

I'm aware of current practice of using Executors instead of ThreadGroup:

  • generally preferred way to deal with Threads
  • catching exceptions from threads, etc...

However, what are the inherent flaws of ThreadGroup as such (I've heard a vague criticism for that class)?

Thanks for answer.

PS. this does not seem to answer this question.

+4  A: 

This is explained in Effective Java 2nd Ed., Item 73.

Thread groups were originally envisioned as a mechanism for isolating applets for security purposes. They never really fulfilled this promise, and their security importance has waned to the extent that they aren’t even mentioned in the standard work on the Java security model [Gong03].

[...] In an ironic twist, the ThreadGroup API is weak from a thread safety standpoint. To get a list of the active threads in a thread group, you must invoke the enumerate method, which takes as a parameter an array large enough to hold all the active threads. The activeCount method returns the number of active threads in a thread group, but there is no guarantee that this count will still be accurate once an array has been allocated and passed to the enumerate method. If the thread count has increased and the array is too small, the enumerate method silently ignores any threads for which there is no room in the array.

The API that lists the subgroups of a thread group is similarly flawed. While these problems could have been fixed with the addition of new methods, they haven’t, because there is no real need: thread groups are obsolete.

Prior to release 1.5, there was one small piece of functionality that was available only with the ThreadGroup API: the ThreadGroup.uncaughtException method was the only way to gain control when a thread threw an uncaught exception. This functionality is useful, for example, to direct stack traces to an application- specific log. As of release 1.5, however, the same functionality is available with Thread’s setUncaughtExceptionHandler method.

To summarize, thread groups don’t provide much in the way of useful functionality, and much of the functionality they do provide is flawed. Thread groups are best viewed as an unsuccessful experiment, and you should simply ignore their existence. If you design a class that deals with logical groups of threads, you should probably use thread pool executors (Item 68).

Péter Török
@Pete: Thanks for quote. So do I correctly understand that we in our practice should completely avoid ThreadGroup inspite of the fact that it still remains inside Thread methods: start() and init(ThreadGroup g, Runnable target, String name, long stackSize), the latter is called from Thread() constructor and always builds ThreadGroup?
Max
Thanks for marking CW and for the ref. Finally bought the book but haven't got that far yet. The `uncaughtException` functionality was actually the last bit I was curious about.
Mark Peters
@Max General-purpose library code should still be aware of which `ThreadGroup` it is creating theads in. So, for some purposes, you still have to deal with it.
Tom Hawtin - tackline
@Max, usually yes (with some exceptions, as @Tom noted). Note that since Executor is preferable to dealing with Threads directly, you should hardly ever even see a ThreadGroup anymore.
Péter Török