Every Java Thread
belongs to some ThreadGroup
and may
be constrained and controlled through the methods of that ThreadGroup
. Similarly, every ThreadGroup
is itself contained in some
parent ThreadGroup
. Thus, there is
a hierarchy of thread groups and the threads they contain. Example 4-3 shows a ThreadLister
class, with a public listAllThreads( )
method that displays this
hierarchy by listing all threads and thread groups currently running
on the Java interpreter. This method displays the name and priority of
each thread, as well as other information about threads and thread
groups. The example defines a main(
)
method that creates a simple Swing user interface and uses
it to display a listing of its own threads. Figure 4-1 shows such a
listing.
The listAllThreads( )
method uses the static Thread
method currentThread( )
to obtain
the current thread and then calls getThreadGroup( )
to find the thread group
of that thread. The method then uses the ThreadGroup.getParent( )
method to move up
through the thread-group hierarchy until it finds the root thread
group, the thread group that contains all other threads and thread
groups.
Now listAllThreads( )
calls the private ThreadLister.printGroupInfo( )
method to
display the contents of the root thread group and then recursively
display the contents of all the thread groups it contains. printGroupInfo( )
, and the printThreadInfo( )
method it calls, use
various Thread
and ThreadGroup
methods to obtain information
about the threads and their groups. Note that the isDaemon( )
method returns, regardless of
whether a thread is a daemon thread. Daemon threads are background
threads that are not expected to exit. The Java interpreter exits when
all nondaemon threads have quit.
The ThreadLister
class has a main( )
method, so it
can be run as a standalone program. It is more interesting, of course,
to invoke the listAllThreads( )
method from within another program; it can also help you to diagnose
problems you are having with threads.
Example 4-3. ThreadLister.java
package je3.thread; import java.io.*; import java.awt.*; // AWT classes for the demo program import javax.swing.*; // Swing GUI classes for the demo /** * This class contains a useful static method for listing all threads * and threadgroups in the VM. It also has a simple main( ) method so it * can be run as a standalone program. **/ public class ThreadLister { /** Display information about a thread. */ private static void printThreadInfo(PrintWriter out, Thread t, String indent) { if (t == null) return; out.println(indent + "Thread: " + t.getName( ) + " Priority: " + t.getPriority( ) + (t.isDaemon( )?" Daemon":"") + (t.isAlive( )?"":" Not Alive")); } /** Display info about a thread group and its threads and groups */ private static void printGroupInfo(PrintWriter out, ThreadGroup g, String indent) { if (g == null) return; int num_threads = g.activeCount( ); int num_groups = g.activeGroupCount( ); Thread[ ] threads = new Thread[num_threads]; ThreadGroup[ ] groups = new ThreadGroup[num_groups]; g.enumerate(threads, false); g.enumerate(groups, false); out.println(indent + "Thread Group: " + g.getName( ) + " Max Priority: " + g.getMaxPriority( ) + (g.isDaemon( )?" Daemon":"")); for(int i = 0; i < num_threads; i++) printThreadInfo(out, threads[i], indent + " "); for(int i = 0; i < num_groups; i++) printGroupInfo(out, groups[i], indent + " "); } /** Find the root thread group and list it recursively */ public static void listAllThreads(PrintWriter out) { ThreadGroup current_thread_group; ThreadGroup root_thread_group; ThreadGroup parent; // Get the current thread group current_thread_group = Thread.currentThread( ).getThreadGroup( ); // Now go find the root thread group root_thread_group = current_thread_group; parent = root_thread_group.getParent( ); while(parent != null) { root_thread_group = parent; parent = parent.getParent( ); } // And list it, recursively printGroupInfo(out, root_thread_group, ""); } /** * The main( ) method creates a simple graphical user interface to display * the threads in. This allows us to see the "event dispatch thread" used * by AWT and Swing. **/ public static void main(String[ ] args) { // Create a simple Swing GUI JFrame frame = new JFrame("ThreadLister Demo"); JTextArea textarea = new JTextArea( ); frame.getContentPane( ).add(new JScrollPane(textarea), BorderLayout.CENTER); frame.setSize(500, 400); frame.setVisible(true); // Get the threadlisting as a string using a StringWriter stream StringWriter sout = new StringWriter( ); // To capture the listing PrintWriter out = new PrintWriter(sout); ThreadLister.listAllThreads(out); // List threads to stream out.close( ); String threadListing = sout.toString( ); // Get listing as a string // Finally, display the thread listing in the GUI textarea.setText(threadListing); } }
Get Java Examples in a Nutshell, 3rd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.