JDK-4773384 : 1.4 doesn't throw IllegalThreadStateException
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.1.6,1.2.0,1.3.0,1.3.1,1.4.1
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS:
    generic,linux,solaris_2.4,solaris_8,windows_nt,windows_2000 generic,linux,solaris_2.4,solaris_8,windows_nt,windows_2000
  • CPU: x86,sparc
  • Submitted: 2002-11-04
  • Updated: 2004-03-29
  • Resolved: 2003-06-05
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
5.0 tigerFixed
Related Reports
Duplicate :  
Duplicate :  
Description
JDK 1.4 does not throw the IllegalThreadStateException if the thread's function
start() is called twice.  Strangely enough, it seems as if the 1.4 JVM optimized
the loop so that the dummy1's start() is only called once.

I can make the program to throw IllegalThreadStateException by:

- Run it with jdk 1.2 or lower.

- Comment out the dummy2 instantiation and start i.e.
  // (new dummy2()).start();

Please see the following attachment of program's output and code sample.

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

%jdk1.4 test
Gonna call start()!
dummy1 done!
Done calling start()!
Gonna call start()!
dummy2 done!
Done calling start()!
dummy2 done!

% jdk1.2 test
Gonna call start()!
Done calling start()!
Gonna call start()!
Exception in thread "main" java.lang.IllegalThreadStateException
	at java.lang.Thread.start(Native Method)
	at test.<init>(Compiled Code)
	at test.main(Compiled Code)
dummy1 done!
dummy2 done!

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

public class test {
    private dummy1 t1 = new dummy1();

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

    test() {
	for (int j = 0; j < 2; j++) {
	    System.out.println("Gonna call start()!");
	    t1.start();
	    (new dummy2()).start();
	    System.out.println("Done calling start()!");
	}
    }

    public class dummy1 extends Thread {
	public void run() {
	    System.out.println("dummy1 done!");
	}
    }

    public class dummy2 extends Thread {
	public void run() {
	    System.out.println("dummy2 done!");
	}
    }

}

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b08 VERIFIED IN: tiger-beta2
14-06-2004

SUGGESTED FIX In JVM_StartThread, check for the thread ever being started. We will have released the Java thread (held at java_lang_Thread::thread) if the thread has exited, so the check cannot be in the if (thr != NULL) block. sccs diffs jvm.cpp ------- jvm.cpp ------- 1860,1870c1860,1866 < JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)); < if (thr != NULL) { < // Thread already started or has stopped < if (java_lang_Thread::is_stillborn(JNIHandles::resolve_non_null(jthread))) { < // Thread has run and been stopped or exited, restarting is a no-op < return; < } else { < // Thread already started, still running, restarting is an error < MutexUnlocker mu(Threads_lock); < THROW(vmSymbols::java_lang_IllegalThreadStateException()); < } --- > oop java_thread = JNIHandles::resolve_non_null(jthread); > if (java_lang_Thread::thread(java_thread) != NULL || > java_lang_Thread::is_stillborn(java_thread)) { > // We're trying to restart an active thread or trying to > // restart a dead thread. In either case, that's an error. > MutexUnlocker mu(Threads_lock); > THROW(vmSymbols::java_lang_IllegalThreadStateException()); 1872c1868 < jlong size = java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); --- > jlong size = java_lang_Thread::stackSize(java_thread); Also, note that JavaThread::thread_main_inner will not call entry_point if the thread is stillborn; it will just delete the thread. This is why the observed behavior is in the description... in Hotspot today, we create a new thread, but while starting it we see it's been marked as stillborn, so we just exit the thread immediately. ###@###.### 2002-11-06 ----------------------------------------------------------- Fixed as above, also some minor cleanups. Putback message: Fixed 4773384 1.4 doesn't throw IllegalThreadStateException (the following two are dups) 4180576 Thread.start() doesn't throw IllegalThreadStateException 4422466 IllegalThreadStateException: Dead Thread not thrown in 1.3.0 These three bugs are all duplicates: in Hotspot, we weren't throwing an IllegalThreadStateException in JVM_StartThread if the thread was stillborn. Instead, we were silently returning. Reviewed by: Coleen, Paul, Fred Fix verified (y/n): y Verification testing: Test cases for 4773384, 4180576, 4422466. JCK test api/java_lang/Thread/index.html#start [Thread1602, Thread1603] (currently on exclude list) Other testing: Solaris/sparc: JCKs (api, lang, vm), -client and -server NSK standard testlist, -client and -server Solaris/x86: JCKs (api, lang, vm), -client NSK standard testlist, -client Linux/x86: JCKs (api, lang, vm), -server Files: update: src/share/vm/prims/jvm.cpp Examined files: 1 Contents Summary: 1 update ###@###.### 2003-04-28 ----------------------------------------------------------
28-04-2003

EVALUATION As noted in the description, the Hotspot VM does not raise the exception if the thread has already stopped or exited; it treats the start request as a no-op. ###@###.### 2002-11-05 Tested with other versions: 1.1.8 and 1.2.2_06 throw the exception; only the hotspot based VMs don't. ###@###.### 2002-11-06 This problem will be fixed in the next major release of the JDK. We will not fix it in a minor release because of compatibility issues. The fix will be to throw the exception regardless of whether the thread has completed running (if it was *ever* started before, we'll throw the exception). ###@###.### 2002-11-06
06-11-2002