I've discovered that any methods which recurse through ThreadGroup
heirarchies are very susceptible to deadlock. For example,
ThreadGroup.activeGroupCount() and possibly ThreadGroup.enumerate().
Here's what happens. When a thread is end-of-lifed, the VM calls
Thread.exit() on it. Thread.exit() removes the thread from its
thread group using TheadGroup.remove(), which grabs a lock (*1).
ThreadGroup.remove() calls ThreadGroup.destroy() if the thread group
is empty. ThreadGroup.destroy() calls parent.destroy(), which tries
to grab the parent's lock (*2).
However, it can't grab the lock because some other thread has called
activeGroupCount(), which has recursed far enough down the group tree
to already be holding lock (*2).
The activeGroupCount() thread holds (*2), but wants (*1).
The ThreadGroup.remove() thread holds (*1), but wants (*2).
Looks like a deadlock to me!
A common user of ThreadGroup.activeGroupCount() is the HotJava
ThreadCountApplet. We're seeing deadlocks of this sort when running
the HJ thread viewer on Kona. Presumably this is affecting other
platforms as well.
Attached is a thread dump of this deadlock in progress. The ThreadCountApplet
is holds the lock of a ThreadGroup from which several threads are trying to
exit:
ThreadCountApplet holds ThreadGroup, wants AppletThreadGroup.
updateThread holds AppletThreadGroup, wants ThreadGroup.
stuart.ritchie@Eng 1996-10-06
heirarchies are very susceptible to deadlock. For example,
ThreadGroup.activeGroupCount() and possibly ThreadGroup.enumerate().
Here's what happens. When a thread is end-of-lifed, the VM calls
Thread.exit() on it. Thread.exit() removes the thread from its
thread group using TheadGroup.remove(), which grabs a lock (*1).
ThreadGroup.remove() calls ThreadGroup.destroy() if the thread group
is empty. ThreadGroup.destroy() calls parent.destroy(), which tries
to grab the parent's lock (*2).
However, it can't grab the lock because some other thread has called
activeGroupCount(), which has recursed far enough down the group tree
to already be holding lock (*2).
The activeGroupCount() thread holds (*2), but wants (*1).
The ThreadGroup.remove() thread holds (*1), but wants (*2).
Looks like a deadlock to me!
A common user of ThreadGroup.activeGroupCount() is the HotJava
ThreadCountApplet. We're seeing deadlocks of this sort when running
the HJ thread viewer on Kona. Presumably this is affecting other
platforms as well.
Attached is a thread dump of this deadlock in progress. The ThreadCountApplet
is holds the lock of a ThreadGroup from which several threads are trying to
exit:
ThreadCountApplet holds ThreadGroup, wants AppletThreadGroup.
updateThread holds AppletThreadGroup, wants ThreadGroup.
stuart.ritchie@Eng 1996-10-06