Thread Group Methods

Other than some deprecated methods that we’ll examine in the next section, the methods of the ThreadGroup class are mostly informative. We’ll examine all the methods of the ThreadGroup class in this section.

Finding Thread Groups

There are often times when you’d like to call one of the thread group methods but don’t necessarily have a thread group object. The Thread class has a method that returns a reference to the thread group of a thread object:

ThreadGroup getThreadGroup()

Returns the ThreadGroup reference of a thread, for example:

// Find the thread group of the current thread.
ThreadGroup tg = Thread.currentThread().getThreadGroup();

You can also retrieve the parent thread group of an existing thread group with the getParent() method of the ThreadGroup class:

ThreadGroup getParent()

Returns the ThreadGroup reference of the parent of a thread group.

Finally, you can test whether a particular thread group is an ancestor of another thread group with the parentOf() method of the ThreadGroup class:

boolean parentOf(ThreadGroup g)

Returns true if the group g is an ancestor of a thread group.

Note that the parentOf() method is badly named; it returns true if the group g is the same as the calling thread group, or the parent of the thread group, or the grandparent of the thread group, and so on up the thread group hierarchy.

Enumerating Thread Groups

The next set of methods we’ll explore allows you to retrieve a list of all threads in a thread group. Enumeration of threads is really the responsibility of the ThreadGroup class: although the Thread class also contains methods that enumerate threads, those methods simply call their counterpart methods of the ThreadGroup class.

There are two basic methods in the ThreadGroup class that return a list of threads:

int enumerate(Thread list[])

Fills in the list array with a reference to all threads in this thread group and all threads that are in groups that descend from this thread group.

int enumerate(Thread list[], boolean recurse)

Fills in the list array with a reference to all threads in this thread group and, if recurse is true, all threads that are in groups that descend from this thread group.

These calls fill in the input parameter list with a thread reference for each appropriate thread and return the count of threads that were inserted into the array. The appropriateness of a thread depends on the recurse parameter: if recurse is true, all threads of the given thread group are returned as well as all threads that are in thread groups that descend from the current thread group. Not surprisingly, calling the enumerate() method with recurse set to false returns only those threads that are actually members of the current thread group.

Calling the enumerate() method with recurse set to true on the system thread group returns all the threads in the virtual machine. You can find the system thread group by using the getParent() method we just examined (subject, of course, to the security model that may be in place).

Since arrays in Java are of a fixed size, the size of the list parameter must be determined before the enumerate() method is called (or you may not get a complete list). To find the correct size for the list array, use the activeCount() method:

int activeCount()

Returns the number of active threads in this and all descending thread groups.

There is no recursion option available with this method; the activeCount() method always returns the count of all threads in the current and in all descending thread groups.

The following code fragment shows how to use these methods to display the threads in the current thread group. Changing the parameter in the enumerate() method displays the threads in this and all descending groups:

ThreadGroup tg = Thread.currentThread().getThreadGroup();
int n = tg.activeCount();
Thread list[] = new Thread[n];
int count = tg.enumerate(list, false);
System.out.println("Threads in thread group " + tg);
for (int i = 0; i < count; i++)
    System.out.println(list[i]);

You can also request an enumeration of ThreadGroup objects rather than Thread objects via the enumerate() method with these signatures:

int enumerate(ThreadGroup list[])

Retrieves all thread group references that are descendants of the given thread group. This method operates recursively on the thread group hierarchy.

int enumerate(ThreadGroup list[], boolean recurse)

Retrieves all thread group references that are immediate descendants of the given thread group and, if recurse is true, all descendants of the current thread group.

These methods are conceptually equivalent to the methods that we’ve just discussed. To determine the size of the list parameter, use the activeGroupCount() method:

int activeGroupCount()

Returns the number of thread group descendants (at any level) of the given thread group.

Recall that the Thread class also had an enumerate() method. The Thread class’s enumerate() method always searches recursively; it is really shorthand for:

Thread.currentThread().getThreadGroup().enumerate(list, true);

Similarly, the Thread class’s activeCount() method is really shorthand for:

Thread.currentThread().getThreadGroup().activeCount();

Finally, there is a method useful only for debugging:

void list()

Sends a list of all the threads in the current thread group to standard out.

Thread Group Priority Calls

Java thread groups carry with them the notion of a maximum priority. This maximum priority interacts with the priority methods of the Thread class: the priority of a thread cannot be set higher than the maximum priority of the thread group to which it belongs. By default, the maximum priority of a thread group is the same as the maximum priority of its parent thread group. As you might have guessed, the maximum priority of the system thread group is 10 (Thread.MAX_PRIORITY ). The maximum priority of the applet thread group—the group to which all threads in an applet belong—is only 6.

There are two methods that handle a thread group’s priority:

void setMaxPriority(int priority)

Sets the maximum priority for the thread group.

int getMaxPriority()

Retrieves the maximum priority for the thread group.

In the reference release of the Java virtual machine, the maximum priority of a thread group is enforced silently: if the thread group to which your thread belongs has a maximum priority of 6 and you attempt to raise your thread’s priority to 8, your thread is silently given a priority of 6. In some browsers (and in Java 1.0), if you attempt to set an individual thread’s priority higher than the maximum priority of the thread group, a SecurityException will be thrown.

Once the maximum priority of a thread group has been lowered, it cannot be raised.

These values are only checked when a thread’s priority is actually changed. Thus, if you have a thread group with a maximum priority of 10 that contains a thread with a priority of 8, changing the thread group’s maximum priority to 6 doesn’t affect that thread: it continues to have a priority of 8 until that thread’s set-Priority() method is called. However, the maximum priority of any nested thread groups is changed immediately: any thread groups that are contained within the target thread group will have their maximum priority lowered to the requested value. This change is propagated recursively throughout the thread group hierarchy.

Destroying Thread Groups

A thread group can be destroyed with the destroy() method:

void destroy()

Cleans up the thread group and removes it from the thread group hierarchy.

The destroy() method is of limited use: it can only be called if there are no threads presently in the thread group. The destroy() method operates recursively, so it destroys not only the target thread group but all thread groups that descend from the target thread group. If any of these thread groups have active threads within them, the destroy() method generates an IllegalThreadState-Exception.

You can test to see if the destroy() method has been called on a particular thread group by using this method:

boolean isDestroyed() ( Java 1.1 and above only)

Returns a flag indicating whether the thread group has been destroyed.

This may seem somewhat confusing: if the thread group has been destroyed, how can we execute a method on it? The answer is that the destroy() method only removes the thread group from the thread group hierarchy; the actual thread group object will not be garbage collected until there are no valid references to it.

Daemon Thread Groups

The ThreadGroup class has the notion of a daemon thread group, which is similar to the notion of a daemon thread. The two are unrelated, however: daemon threads can belong to non-daemon thread groups, and a daemon thread group can contain non-daemon threads. The benefit of a daemon thread group is that it is destroyed automatically once all the threads it contains have exited and all the groups that it contains have been destroyed. Unlike a thread, a thread group’s daemon status can be changed at any time:

void setDaemon(boolean on)

Changes the daemon status of the thread group.

boolean isDaemon()

Returns true if the thread group is a daemon group.

We should stress that a daemon thread group is destroyed only if all threads in the group have actually exited: if there are only daemon threads in a daemon thread group, the daemon thread group is not destroyed unless the daemon threads it contains are stopped first. This is because daemon threads serve user threads throughout the virtual machine, not just the user threads of a particular thread group.

Of course, the benefit of daemon threads in the first place is that the programmer never bothers to stop them explicitly. Thus, while the concept of a daemon thread group that automatically exits when it contains only daemon threads may be attractive, it does not work that way.

Miscellaneous Methods

There are three remaining methods of the ThreadGroup class that we will mention here for completeness:

String getName()

Returns the name of the thread group.

void uncaughtException(Thread t, Throwable e)

This method is called when a thread exits due to an uncaught exception; its default behavior is to print the stack trace of the thread to System.err. We’ll say more about this method in Appendix A.

boolean allowThreadSuspension(boolean b) ( Java 1.1 only)

Sets the vmAllowSuspension flag of the thread group, returning the old value. When the virtual machine runs low on memory, some implementations of the virtual machine will seek to obtain memory by suspending threads in thread groups for which the vmAllowSuspension flag is set to true.

However, since the suspend() method itself is deprecated in Version 2, the virtual machine can no longer suspend threads within a group that is marked to allow thread suspension, so this method is not terribly useful.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset