JDK-4216667 : Thread.stop() does not always work (problem with fix for 4145910)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.1.8
  • Priority: P1
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: generic
  • CPU: generic
  • Submitted: 1999-03-03
  • Updated: 1999-03-17
  • Resolved: 1999-03-17
Related Reports
Relates :  
Relates :  
Relates :  
Description
There is a potential problem with the new implementation of Thread.stop() used to fix bugs 4145906 and 4145910.
If stop() is called on Thread after start() but before it has had a chance to execute its run() method, the stop() can be ignored and the Thread continues to execute.

class SimpleThread implements Runnable {

    SimpleThread() {
        Thread thread = new Thread(this);
        thread.start();
        System.out.println("Thread.start() returned");
        thread.stop();    
        System.out.println("Thread.stop() returned");
        while (thread.isAlive()) {
            System.out.println("thread is alive");
            try {
                Thread.sleep(100);
                System.out.println("Waiting for thread to die");
            } catch(InterruptedException ie) {}
        }
    }

    public void run() {
        System.out.println("in run");
        try {
            Thread.sleep(1000);
        } catch(InterruptedException ie) {}
        System.out.println("thread finished execution");
    }

    public static void main(String args[]) {
        new SimpleThread();
    }

}

The following is the output when running JDK1.1.8 build H on an Ultra 1 Sparc (I guess it's possible that the problem may not be easily reproduced on different machines as it is critically dependent on timing):

$ /usr/local/java/jdk1.1.8/solaris/bin/java SimpleThread
Thread.start() returned
Thread.stop() returned
thread is alive
in run
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
Waiting for thread to die
thread is alive
thread finished execution
Waiting for thread to die

For 1.1.7B, the run() method is never executed:

$ /usr/local/java/jdk1.1.7/solaris/bin/java SimpleThread
Thread.start() returned
Thread.stop() returned

stuart.lawrence@eng 1999-03-02

Comments
EVALUATION Closing this bug as no longer existing as the fix that caused this problem has been removed. This fix was removed from 1.1.8. lara.bunni@Eng 1999-03-17
17-03-1999

SUGGESTED FIX The problem occurs due to changes in src/share/java/lang/thread.c function void java_lang_Thread_stop0: 1.1.8 build H: tid = (struct Classjava_lang_Thread *) unhand(p); if (tid->PrivateInfo == 0) { tid->stillborn = 1; } else if (!tid->stillborn) { (void) threadPostException(p, exc); } 1.1.7B: tid = (struct Classjava_lang_Thread *) unhand(p); if (tid->PrivateInfo && !tid->stillborn) { tid->stillborn = 1; (void) threadPostException(p, exc); } When this function is entered for PrivateInfo!=0 and stillborn==0 then, for 1.1.7B the stillborn flag is set to true and an exception is thrown. For 1.1.8, the stillborn flag remains zero and the exception is thrown. However, if at this point the thread is unready to process such an exception, the call to stop() has no affect and the thread continues to execute. A partial fix would be to set stillborn=1, before throwing the exception in java_lang_Thread_stop0. tid = (struct Classjava_lang_Thread *) unhand(p); if (tid->PrivateInfo == 0) { tid->stillborn = 1; } else if (!tid->stillborn) { tid->stillborn = 1; <-- new line here (void) threadPostException(p, exc); } This prevents isAlive() returning true after stop(). However, this change preserves the fix for 4145906 but breaks the fix for 4145910. Instead, introduce another flag to denote "stop() after start() but before run()". In java_lang_Thread_stop0 we can set this flag to true, and check its value in ThreadRT0 before executing the run method. Above becomes: tid = (struct Classjava_lang_Thread *) unhand(p); if (tid->PrivateInfo == 0) { tid->stillborn = 1; } else if (!tid->stillborn) { tid->stop_before_run = 1; <-- new line here (void) threadPostException(p, exc); } In src/share/java/java/lang/Thread.java 124a125,128 > /* Whether or not this thread was asked to stop after it starts > but before its run method executes. */ > private boolean stop_before_run = false; > and in ThreadRT0 in thread.c: if (unhand(p)->stillborn) { /* This thread was asked to exit before it got to run */ threadExit(); } > else if (unhand(p)->stop_before_run) { > /* This thread was asked to stop() after start() but before it > executed its run() method */ > threadExit(); > } execute_java_dynamic_method(&ee, (void *)p, "run", "()V"); stuart.lawrence@eng 1999-03-02
02-03-1999