--- old/test/java/lang/ThreadGroup/Stop.java 2016-07-11 16:20:08.000000000 +0800 +++ new/test/java/lang/ThreadGroup/Stop.java 2016-07-11 16:20:08.000000000 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,39 +24,55 @@ /** * @test * @bug 4176355 + * @library /test/lib/share/classes + * @modules java.base/jdk.internal.misc * @summary Stopping a ThreadGroup that contains the current thread has * unpredictable results. */ -public class Stop implements Runnable { - private static boolean groupStopped = false ; - private static final Object lock = new Object(); +import java.util.concurrent.CountDownLatch; +import jdk.test.lib.Utils; + +public class Stop { + + private static final long LONG_DELAY_MS = Utils.adjustTimeout(5000L); + private static final CountDownLatch ready = new CountDownLatch(1); + private static final CountDownLatch done = new CountDownLatch(2); private static final ThreadGroup group = new ThreadGroup(""); - private static final Thread first = new Thread(group, new Stop()); - private static final Thread second = new Thread(group, new Stop()); - public void run() { - while (true) { - // Give the other thread a chance to start - try { - Thread.sleep(1000); - } catch (InterruptedException e) { + private static final Thread second = new Thread(group, () -> { + ready.countDown(); + try { + while (true) { + // keep it alive } + } catch (final ThreadDeath td) { + done.countDown(); + throw td; + } + }); - // When the first thread runs, it will stop the group. - if (Thread.currentThread() == first) { - synchronized (lock) { - try { - group.stop(); - } finally { - // Signal the main thread it is time to check - // that the stopped thread group was successful - groupStopped = true; - lock.notifyAll(); - } - } - } + private static final Thread first = new Thread(group, () -> { + // Wait until "second" is started + await(ready); + try { + // Now stop the group + // ThreadDeath then is thrown in the victim threads + group.stop(); + } catch (final ThreadDeath td) { + // Inform the main thead that the test thread has completed + done.countDown(); + // Rethrow the object so that the thread actually dies + throw td; + } + }); + + private static void await(CountDownLatch latch) { + try { + latch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } } @@ -65,23 +81,21 @@ first.start(); second.start(); - // Wait for the thread group stop to be issued - synchronized(lock){ - while (!groupStopped) { - lock.wait(); - // Give the other thread a chance to stop - Thread.sleep(1000); + try { + // Wait for the thread group stop to be issued + await(done); + + // Check that the second thread is terminated when the + // first thread terminates the thread group. + second.join(LONG_DELAY_MS); + boolean failed = second.isAlive(); + if (failed) { + throw new RuntimeException("Failure."); } + } finally { + // Clean up any threads that may have not been terminated + first.stop(); + second.stop(); } - - // Check that the second thread is terminated when the - // first thread terminates the thread group. - boolean failed = second.isAlive(); - - // Clean up any threads that may have not been terminated - first.stop(); - second.stop(); - if (failed) - throw new RuntimeException("Failure."); } }