Race condition in ThreadGroup stop test

Gary Adams gary.adams at oracle.com
Tue Nov 8 13:12:17 UTC 2011


  Let's see if this captures all the comments and
is a bit more robust in the face of the original
race conditions mentioned.
     - threads are started before they are recorded in local variables
     - second is now volatile
     - stop thread group is triggered by first thread once second thread is started
     - main thread checks for second thread death after thread group is stopped
     - left in the sleep delays to yield to other threads
     - using wait/notify for handshake with main thread
     - using try/finally to ensure main thread does not check too soon
       after thread group stop

     31    public class Stop implements Runnable {
     32        private static Thread first=null;
     33        private static volatile Thread second=null;
     34        private static ThreadGroup group = new ThreadGroup("");
     35        private static boolean groupStopped =false ;
     36        private static final  Object lock = new Object();
     37
     38        Stop() {
     39            Thread thread = new Thread(group, this);
     40            thread.start();
     41            // Record the threads after they have been started
     42            if (first == null)
     43                first = thread;
     44            else
     45                second = thread;
     46        }
     47
     48        public void run() {
     49            while (true) {
     50                try {
     51                    // Give the other thread a chance to start
     52                    Thread.sleep(1000);
     53                } catch(InterruptedException e) {
     54                }
     55
     56                // When the first thread sees the second thread has been 
started
     57                // stop the thread group.
     58                if ((Thread.currentThread() == first)
     59 && (second != null)) {
     60                    synchronized (lock) {
     61                        try {
     62                            group.stop();
     63                        } finally {
     64                            // Signal the main thread it is time to check
     65                            // that the stopped thread group was successful
     66                            groupStopped = true;
     67                            lock.notifyAll();
     68                        }
     69                    }
     70                }
     71            }
     72        }
     73
     74        public static void main(String[] args) throws Exception {
     75            // Launch two threads as part of the same thread group
     76            for (int i = 0; i < 2; i++)
     77                new Stop();
     78
     79            // Wait for the thread group to be issued
     80            synchronized(lock){
     81                while (!groupStopped){
     82                    lock.wait();
     83                    try {
     84                        // Give the other thread a chance to stop
     85                        Thread.sleep(1000);
     86                    } catch(InterruptedException e) {
     87                    }
     88                }
     89            }
     90
     91            // Check that the second thread is terminated when the
     92            // first thread terminates the thread group.
     93            boolean failed = second.isAlive();
     94
     95            // Clean up any threads that may have not been terminated
     96            first.stop();
     97            second.stop();
     98            if (failed)
     99                throw new RuntimeException("Failure.");
    100        }
    101    }




More information about the core-libs-dev mailing list