by Prithvi Rao
Prithvi Rao is the co-founder of KiwiLabs, which specializes in soft-ware engineering methodology and Java/ CORBA training. He has also worked on the de-velopment of the MACH OS and a real-time version of MACH. He is an adjunct faculty at Carnegie Mellon and teaches in the Heinz School of Public Policy and Management.
In a previous article I introduced the use of threads within Java. It is necessary to have a deeper understanding of this topic in order to write serious Java applications. This article presents an introduction to the ThreadGroup class. This class serves to organize threads. In a limited sense, it is analogous to the concept of databases, in which semantically similar pieces of information are grouped in a common repository. Naturally, another such example is a directory (analogous to the thread group) and an individual file (a thread).
Thread Group Characteristics
One of the key characteristics of thread groups is that it is possible to affect the state of all threads in the hierarchy with a single call. For instance, it is possible to stop every thread in the thread group with a single call. This is one reason to use thread groups.
Consider the following code:
ThreadGroup A = new ThreadGroup("A");
The resulting hierarchy is as follows:
From main, A and E are descendants. ThreadGroup B is a descendant of A, and so is ThreadGroup C. Finally, ThreadGroup D is a descendant of C.
One way to improve the performance of an application utilizing thread groups is to use a single call to affect the state of threads in a hierarchy. If this were not possible, then each branch of the tree would have to be traversed, and this could be a time-consuming operation.
Another application for thread groups is in a multiprocessing environment. A given CPU may run threads that are in a given group (this needs operating-system support, however), and it is possible to assign different priorities to the different thread groups depending on the application. Generally, however, this requires significant operating-system support not usually found on nonrealtime systems.
Although at the time of this writing there are not too many examples of JVMs that have been ported to running on realtime operating systems, this is likely to happen, given that modern-day audio and video applications must meet strict time deadlines.
The main Thread Group
When you start an application, the thread group is main. Unless otherwise specified, all threads will be created as part of the main thread group. If you run applets within a browser, the name of the root thread group will depend on the browser.
Creating a new thread without specifying a thread group in the thread's constructor places the thread in the same thread group as the creator.
The following three thread constructors create the thread in a specific thread group.
It is possible to learn to which thread group a particular thread belongs by using the getThreadGroup() method.
ThreadGroup Z = foo.getThreadGroup();
It is also possible to enumerate threads within a particular thread group. Consider the following:
ThreadGroup X = Thread.currentThread().getThreadGroup();
ThreadGroup X = new ThreadGroup("BackGround");
The threads Y and Z are usually created with the default priority of NORMAL_PRIORITY, which is equal to 5. In the example above, before Z was created the maximum priority was set to MIN_PRIORITY+2, which is now 3. So the creation of Z results in its priority value of 3.
Thread Groups and Priorities
Attempting to set the priority of a thread higher than the priority of the thread group to which it belongs will result in SecurityException being thrown.
Once the maximum priority of a thread group has been lowered, it cannot be raised.
The maximum priority of the system ThreadGroup is MAX_PRIORITY (10). The maximum priority of the applet ThreadGroup is 6.
Thread Groups and Security
void checkAccess(Thread t)
void checkAccess(ThreadGroup g)
Most of the methods in the Thread class and the ThreadGroup class call SecurityManager before performing the actual operation. For example, the implementation of stop() reveals the following:
public void stop()
The Java Security Manager implements security on an "all-or-none" basis. In other words, there is no granularity to distinguish allowable operations. If the Security Manager does not permit a thread to suspend another thread, then it also does not allow the same thread to set the other thread's daemon status. The setDaemon() function changes the daemon status of the thread group. It does not alter the daemon status of any individual threads within the group. If a group is made a daemon group, then it will be destroyed automatically when all of the threads it contains are terminated.
The following is a list of ThreadGroup methods that call ThreadGroup's checkAccess() method:
ThreadGroup(ThreadGroup parent, String name)
The following Thread methods call checkAccess():
Recall that a standalone Java application has no security manager, so threads can modify and inspect any other thread. Within an applet, a thread can manipulate another thread only if both threads are members of the applet's ThreadGroup. A thread cannot manipulate a thread that is in another applet.
In future articles I will present applications using
ThreadGroup to further demonstrate the use of this important