Thread Enumeration
The Thread class provides a pair of methods that work together to enumerate references to Thread objects (corresponding to all active threads in a program): activeCount() and enumerate(). The activeCount() method returns an integer that specifies the number of active threads. That value is only an estimate and is used to size an array of Thread references. After the array is sized, it can be passed as an argument to the enumerate() method. That method fills the array with references to all active threads' Thread objects. The integer returned by enumerate() identifies the actual number of Thread references stored in the array. That return value should be used instead of activeCount()'s return value, when examining the returned references in a loop.
When is a thread considered active? That is not an easy question to answer. Various sources suggest that a thread is considered to be active after its Thread object is created (even if the corresponding thread has not been started). However, in practice, it appears that a thread must be started in order to be considered active. Regardless, a thread continues to be active until it returns from its run() method. At some point between a Thread object being created and started, its reference is added to an internal enumeration list. That reference is removed when the run() method completes.
To demonstrate activeCount() and enumerate(), the ThreadDemo6 source code in Listing 4 starts a new thread in addition to the main thread. Those threads are then enumerated.
Listing 4: ThreadDemo6.java.
// ThreadDemo6.java class ThreadDemo6 extends Thread { public void run () { for (int i = 0; i < 20; i++) System.out.println ("i = " + i); } public static void main (String [] args) { ThreadDemo6 td6 = new ThreadDemo6 (); td6.start (); Thread [] threads = new Thread [Thread.activeCount ()]; int n = Thread.enumerate (threads); for (int i = 0; i < n; i++) System.out.println (threads [i].toString ()); } }
When you run the program, you'll see Thread[main,5,main] and Thread[Thread-0,5,main] interspersed among the output. However, if you comment out the line containing td6.start ();, you will most likely not see Thread[Thread-0,5,main]. If you don't see Thread[Thread-0,5,main] when td6.start (); is commented out, that proves that, on your platform, a thread is not active until its start() method is called.
What does the information between square brackets mean? For Thread[main,5,main], the leftmost main names the thread, 5 identifies its priority, and the rightmost main identifies the thread group to which the main thread belongs. Similarly, for Thread[Thread-0,5,main], Thread-0 names the thread, 5 is the thread's priority, and main is its thread group. You will learn more about those concepts later in this chapter.
CAUTION
Do not rely on activeCount()'s return value when iterating over an array of active Thread references. Instead, use enumerate()'s return value. If you rely on activeCount()'s return value, your program might end up throwing a NullPointerException object. That happens when enumerate() does not assign Thread references to all elements in the array sized by activeCount()'s return value, and those elements not assigned Thread references contain null references.