JDK-1235445 : Thread.stop() ignored if called soon after start()
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: sparc
  • Submitted: 1996-01-24
  • Updated: 1997-10-22
  • Resolved: 1997-10-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.0.2 1.0.2Fixed
Related Reports
Relates :  
Relates :  
Description
The following extreme test case shows that stop() is ignored if called too
quickly after start.  The program creates a bundle of threads and stops them
all. After stopping each one it prints the value of isAlive(). For me, I get all
the threads being reported alive even though all should be reported dead.

I can imagine there being a concurrency/scheduling problem in stopping
a thread before it has really been started.  However, since the thread has
already been created, in the worst case, it should be possible to store a boolean
in the thread state that is checked when appropriate.

Whatever the problem or solution, this is a serious problem if stop() is really
to be supported, since in a multi-threaded world, it is difficult to know if the
call of stop has succeeded or not?

The test case is extreme in calling stop quite so soon after start, but the test case
is refined from a real case where a real program was refusing to exit because some
threads had not died even though they had been stopped.

-- Jon

----------------------------


public class Bug extends Thread
{
    public static void main(String[] args) {
        Bug[] bugs = new Bug[10];

        for (int i = 0; i < bugs.length; i++) {
  	  bugs[i] = new Bug();
	  bugs[i].start();
	  System.out.println("bugs[" + i + "] = " + bugs[i]);
	  bugs[i].stop();
	  System.out.println("bugs[" + i + "] " +
		 (bugs[i].isAlive() ? "alive" : "dead"));
        }

        System.out.println("main() preparing to exit");
        int n = Thread.activeCount();
	if (n > 0) {
            System.out.println(n + " threads outstanding");
	    Thread[] tarray = new Thread[n];
	    n = Thread.enumerate(tarray);
	    for (int i = 0; i < n; i++) {
	  	System.out.println(tarray[i] + " " +
			(tarray[i].isAlive() ? "alive" : "dead"));
	    }
	}
        System.out.println("main() really exiting");
    }

    public void run() {
	try {
	    wait();
	}
	catch (InterruptedException e) {
	}
    }
}


Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.0.2 FIXED IN: 1.0.2 INTEGRATED IN: 1.0.2
14-06-2004

EVALUATION This bug doesn't actually have anything to do with the thread being alive or dead per se, but rather with Thread.isAlive. There is a flag in the thread object called "stillborn" that is set if a thread is killed before it has had a chance to run enough to initialize the structures that we normally check against. If we try to start a thread but find its stillborn flag set, we exit instead. The code for isAlive was only looking at structures that would be set up once the thread had started running, and was ignoring the stillborn flag, so was reporting the wrong state for the threads in the test. The fix is to check the stillborn flag in java_lang_Thread_isAlive in thread.c. With that fix the bug test shows all threads but main to be dead.
11-06-2004

WORK AROUND The following is a workaround for the test case I provided. After the call to bugs[i].stop(); add the following: // just in case, kick the living daylights out of it while (bugs[i].isAlive()) { System.out.println("bugs[" + i + "] " + (bugs[i].isAlive() ? "alive" : "dead")); bugs[i].stop(); Thread.yield(); } Thus given a Thread t, the following seems to be a way to reliably stop it: t.stop(); while (t.isAlive()) { Thread.yield(); t.stop(); }
11-06-2004

PUBLIC COMMENTS Thread.stop() ignored if called soon after start()
10-06-2004