Name: mf23781 Date: 06/12/98
Thread.join() completes before thread ceases execution.
Thread.join() should not complete until the receiving thread has died.
However, in the current versions of the JDK, Thread.join() completes
as soon as stop() has been issued, rather than when the receiving
thread has completed execution.
//
// Thread.join() completes too early.
//
// The documentation for Thread.join() states:
// "Waits for this thread to die."
//
// "thread died" should imply that the instruction pointer associated with the
// thread never changes again. However, Thread.join() does not implement these semantics.
//
// A thread which has been stopped may not die immediately because a finally clause on its
// stack may be blocked or otherwise delayed for legitimate reasons. However, Thread.join()
// returns immediately for such threads even if the instruction pointer for the thread will change
// subsequently (i.e. more code is executed).
//
// It seems reasonable that Thread.join() should not complete until the thread is truly dead
// as opposed to "almost dead" otherwise the caller cannot make any strong assertions about what
// what other concurrent activity may be in progress.
//
// To compile: java Bug2.java
//
public class Bug2 implements Runnable
{
private boolean running;
private boolean finished;
public Bug2()
{
running = false;
finished = false;
}
public synchronized void waitUntilRunning() throws InterruptedException
{
while (!running) {
wait();
}
}
public synchronized void waitUntilFinished() throws InterruptedException
{
while (!finished) {
wait();
}
}
public void run()
{
try {
synchronized (this) {
running = true;
notifyAll();
try {
while (true) {
wait();
}
} catch (InterruptedException e) {
}
}
} finally {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
synchronized (this) {
finished = true;
notifyAll();
}
}
}
private static void test()
{
Thread t1;
Bug2 b2;
try {
b2 = new Bug2();
t1 = new Thread(b2, "t1");
t1.start();
b2.waitUntilRunning();
t1.stop();
t1.join();
synchronized (b2) {
if (!b2.finished) {
if (!t1.isAlive()) {
System.err.println("failed...isAlive() does not match actual thread state");
}
System.err.println("failed...t1.join() finished prematurely");
b2.waitUntilFinished();
} else {
System.out.println("passed");
}
}
} catch (InterruptedException i) {
}
}
public static void main(String args[])
{
test();
}
}
Discovered on AIX 1.1.6, but also happens on NT 1.1.6,
1.1.7A and 1.2beta4H
======================================================================
- duplicates
-
JDK-4145910 Thread.join() completes too early
- Closed