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