Thread Groups

   

The ThreadGroup class can be used to establish some thread security and authorization constraints on threads. It is also a way to group threads together so that actions can be performed on an entire set of threads. For example, you can start or stop all the threads within a ThreadGroup. After a thread is inserted into a ThreadGroup, it can't be put into a different ThreadGroup.

Most Java developers don't use ThreadGroups. That is, they just create new threads and accept whatever ThreadGroup the default is and put the new thread into that group. By default, all threads that are created belong to the default ThreadGroup of the main thread or a ThreadGroup called main. This is the same ThreadGroup in which the main thread is running.

Threads that belong to a particular ThreadGroup are not allowed to access or change the state of other threads that are in a different ThreadGroup. This restriction includes the parent ThreadGroup of the ThreadGroup or any other ThreadGroup that exists. The ThreadGroup class itself does not enforce this restriction, but rather relies on the SecurityManager that is installed for the running application. The ThreadGroup object works with the SecurityManager that is installed for the running application and together they determine what access is granted and what access is restricted.

ThreadGroups can form trees in which one ThreadGroup can be the parent or child of another ThreadGroup. By creating a custom ThreadGroup and assigning your new threads to this ThreadGroup object, you are locking down your thread's capability to access information about other threads outside of its ThreadGroup.

Caution

If a thread attempts to access another thread that belongs to a different ThreadGroup and the SecurityManager has not granted this access, a SecurityException will be thrown.


Take a look at an example using ThreadGroups. This example isn't too complicated, but it shows how to create a new ThreadGroup other than the default and assign threads into the group. This examples uses a thread called WorkerThread to perform some repetitive task that might need to be performed. The idea here is that there are multiple worker threads created, each one doing something for the overall application. In this case, it's just going to print out that the thread is running. This could have been something like checking a directory for a file, or listening on a socket for a request. This example is simple because the only purpose is to understand the ThreadGroups. Listing 11.15 shows the source for the WorkerThread that belongs to a ThreadGroup.

Listing 11.15 Source Code for WorkerThread.java
 public class WorkerThread extends Thread {   // Boolean flag that keeps state about when the thread should stop   boolean keepRunning = true;   // Default Constructor   public WorkerThread( ThreadGroup group, String threadName )   {     super( group, threadName );   }   // Override the parents run method to do something special   public void run()   {     // While the thread should keep running     while( getKeepRunning() )     {       System.out.println( "Thread " + getName() + " is Running" );       try       {         // Sleep for a time         sleep( 3000 );       }       catch( Exception ex )       {  /* Don't do anything here */ }     }     // Let the user know that this thread is exiting     System.out.println( "Thread: " + getName() + " is stopping" );   }   // public setting method to stop the thread   public synchronized void setKeepRunning( boolean trueOrFalse )   {     keepRunning = trueOrFalse;   }   // public accessor for getting the state of this thread   public synchronized boolean getKeepRunning()   {     return keepRunning;   } } 

The boolean flag keepRunning is similar to the one from the synchronization section. Its used by the worker thread to know when it's time to quit. It needs to be synchronized because both the HandlerThread and the WorkerThread need to access it.

The next class in this example is the handler thread that is responsible for creating the worker threads and also informing them when it's time to stop. Listing 11.16 shows the HandlerThread. The main method is located inside the HandlerThread to keep this example compact

Listing 11.16 Source Code for HandlerThread.java
 public class HandlerThread extends Thread {   // The default constructor for the HandlerThread   public HandlerThread( ThreadGroup ownerGroup, String threadName )   {     super( ownerGroup, threadName );   }   // Override the parents run to do something different   public void run()   {     // How many worker threads to start up int numberOfChildren = 3;     // Declare the reference outside of the loop for better performance     WorkerThread childThread = null;     // Loop through and start up the worker threads     for( int i = 1; i <= numberOfChildren; i++ )     {       childThread = new WorkerThread( getThreadGroup(),                                       "Thread" + String.valueOf(i) );       childThread.start();     }     // Go to sleep for 3 seconds and let the worker threads do something try     {       sleep( 3000 );     }     catch( InterruptedException ex )     {       /* Don't need to handle this for now */     }     // Get the thread group that I belong to     ThreadGroup myGroup = getThreadGroup();     // how many active threads are in my group that I need to stop     int activeEstimatedThreadCount = myGroup.activeCount();     Thread[] activeThreads = new Thread[ activeEstimatedThreadCount ];     // Get the count of active threads     int activeThreadCount = myGroup.enumerate( activeThreads );     // Declare the reference outside of the loop for performance     Thread thread = null;     // Loop through all the active threads and signal them to quit     for( int counter = 0; counter < activeThreadCount; counter++ )     {       // Get one of the active threads out of the array       thread = activeThreads[counter];       // Make sure it's a worker thread. There may be others active       // If it is a worker thread, tell it to stop running       if ( thread instanceof WorkerThread )         ((WorkerThread)thread).setKeepRunning(false);     }   }   public static void main( String args[] )   {     // Create a new ThreadGroup     ThreadGroup threadGroup = new ThreadGroup( "MyNewGroup" );     // Start the handler, which will start the worker threads     HandlerThread handler = new HandlerThread( threadGroup, "HandlerThread" );     // Start the handler thread running     handler.start();   } } 
   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net