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