diff --git a/src/share/classes/java/lang/Thread.java b/src/share/classes/java/lang/Thread.java index c3592cf5cf35748c41d056dbb1e0749e8126cd49..52b57dde4bb7945b07c5b1c8a1e23022843b37f0 100644 --- a/src/share/classes/java/lang/Thread.java +++ b/src/share/classes/java/lang/Thread.java @@ -229,7 +229,7 @@ class Thread implements Runnable { * after setting this thread's interrupt status. */ private volatile Interruptible blocker; - private Object blockerLock = new Object(); + private final Object blockerLock = new Object(); /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code */ @@ -688,16 +688,19 @@ class Thread implements Runnable { throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started - * so that it can be added to the group's list of threads. */ + * so that it can be added to the group's list of threads + * and the group's unstarted count can be decremented. */ group.threadStarting(this); - boolean failed = true; + boolean started = false; try { start0(); - failed = false; + started = true; } finally { try { - group.threadStarted(this, failed); + if (!started) { + group.threadStartFailed(this); + } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ diff --git a/src/share/classes/java/lang/ThreadGroup.java b/src/share/classes/java/lang/ThreadGroup.java index 1b14570cee3837be7dbf8a49abc73e80bebb1f55..8bfc3bc4832904392f8fd8cc8a1be04178bd62be 100644 --- a/src/share/classes/java/lang/ThreadGroup.java +++ b/src/share/classes/java/lang/ThreadGroup.java @@ -870,9 +870,16 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { /** * Notifies the group that the thread {@code t} is about to be * started and adds the thread to this thread group. + * + * The thread is now a fully fledged member of the group, even though + * it hasn't been started yet. It will prevent the group from being + * destroyed so the unstarted Threads count is decremented. */ void threadStarting(Thread t) { - add(t); + synchronized (this) { + add(t); + nUnstartedThreads--; + } } /** @@ -907,12 +914,10 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { } /** - * Notifies the group that the thread {@code t} has completed + * Notifies the group that the thread {@code t} has failed * an attempt to start. * - *

If the thread has been started successfully - * then the group has its unstarted Threads count decremented. - * Otherwise the state of this thread group is rolled back as if the + *

The state of this thread group is rolled back as if the * attempt to start the thread has never occurred. The thread is again * considered an unstarted member of the thread group, and a subsequent * attempt to start the thread is permitted. @@ -923,16 +928,10 @@ class ThreadGroup implements Thread.UncaughtExceptionHandler { * @param failed * true if the thread could not be started successfully */ - void threadStarted(Thread t, boolean failed) { + void threadStartFailed(Thread t) { synchronized(this) { - if (failed) { - remove(t); - } else { - if (destroyed) { - return; - } - nUnstartedThreads--; - } + remove(t); + nUnstartedThreads++; } }