JDK-4833089 : (thread) If main thread dies from unhandled exception, isAlive() is still true
  • Type: Bug
  • Component: tools
  • Sub-Component: launcher
  • Affected Version: 1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-03-15
  • Updated: 2004-03-19
  • Resolved: 2004-03-19
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 b44Fixed
Related Reports
Relates :  
Description

Name: nt126004			Date: 03/14/2003


FULL PRODUCT VERSION :
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1-b24)
Java HotSpot(TM) Client VM (build 1.3.1-b24, mixed mode)

(Also tested with 1.4.1 on Windows and Linux)

FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]

A DESCRIPTION OF THE PROBLEM :
If a thread uses join() to wait for the main thread to terminate, but the main thread exits due to an unhandled exception, the join() does not complete. If join(n) is used, at the end of the timeout period the main thread is reported as alive by isAlive(). The join() terminates normally if the main thread exits normally (i.e. not as the result of an unhandled exception). For threads other than the main thread, join() and isAlive() work as expected.

The outcome is that an application which generates an unhandled exception in the main thread will never terminate if another thread is using isAlive() and/or join() to wait for the main thread to die. The monitoring thread stays alive forever waiting for the (now moribund) main thread to finish, which it never does.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the code below.

Also: comment out the "throw" statement in main to see it working normally in the absence of an unhandled exception. Or, comment out the line "w.start()" near the beginning of main() to see it working normally if an unhandled exception occurs but no other thread is waiting for the main thread to terminate.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
java.lang.RuntimeException: Bang!
	at Termination.main(Termination.java:9)
Joined Thread[main,5,main]
Terminated: Thread[main,5,main]
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
java.lang.RuntimeException: Bang!
	at Termination.main(Termination.java:9)
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
Joined Thread[main,5,main]
Waiting for Thread[main,5,main]
[...and so on...]

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Termination {
  public static void main (String args[]) {
    Waiter w = new Waiter();
    w.start();
    try {
      Thread.currentThread().sleep(1000);
    }
    catch (InterruptedException e) { }
    throw new RuntimeException("Bang!");  // the thread is still
  }                                       // alive after this???
}

class Waiter extends Thread {
  Thread t;
  public Waiter () {
    t = Thread.currentThread();
  }
  public void run () {
    while (t.isAlive()) {
      System.out.println("Waiting for " + t);
      try {
        t.join(500);
      }
      catch (InterruptedException e) {
        System.out.println("Interrupted");
      }
      System.out.println("Joined " + t);
    }
    System.out.println("Terminated: " + t);
  }
}
---------- END SOURCE ----------
(Review ID: 182413) 
======================================================================

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

EVALUATION The reporter is correct. This should be fixed, so that join functions properly. ###@###.### 2003-03-25 Here is a slightly simpler test case: ---------------------------------------------------------- public class InterruptedIsAlive { public static void main(String[] args) throws Exception { final Thread t = Thread.currentThread(); new Thread() { public void run() { try { t.join(1000); } catch (Exception e) {} if (t.isAlive()) System.out.println("Thread should no longer be alive!"); }}.start(); throw new RuntimeException("Bang!"); } } ---------------------------------------------------------- As with the submitter's example, commenting out the `throw' will cause a change in behavior. Probably a hotspot bug. ###@###.### 2004-01-24 Confirmed on both Solaris and Windows as far back as 1.1.6. ###@###.### 2004-01-25 As the fix would be a launcher issue, I'm changing the category appropriately. Since this is (very) long standing behavior, it would need to be altered in a feature release -- committing to Mustang. ###@###.### 2004-01-26
26-01-2004