by Java Q&a Experts

Close the window, Ma: Why Java DOS windows don’t always close (6/7/99)

news
Jun 7, 19993 mins

The JavaWorld experts answer your most pressing Java questions -- every week

Q: I have a Java application that loads an image with Toolkit.getImage(). Even if I flush() the image and set the Image object to null, the Java DOS window doesn’t close. Is this because something is still being referenced?

A:
  1. When all user (non-daemon) threads are completed
  2. By a call to System.exit or by calling exit on the runtime

The first case requires further explanation. The definition of a daemon thread is circular in this discussion. A thread should be made a daemon thread when you don’t want that thread alone to keep the program alive. When a thread is created, it can be marked as a daemon thread with a call to setDaemon(true). (Note that this must be called before the start method.) A thread created from another daemon thread is a daemon thread by default. In most programs with no GUI and no threads created by the developer, the “main” thread is the only non-daemon thread. The program will therefore end when main completes.

So, why does the call to Toolkit.getImage() prevent the program from ending? To explain this, let’s see what threads are running. For this test, we use Sun’s JDK 1.1.7. Note that some details are implementation-dependent and may vary across ports, but the concepts are the same. On Windows, a full thread dump will be printed out if you hit CTRL-Break in the command prompt in which the Java program is running. On Solaris, you can send the kill -QUIT signal to the Java process, or hit CTRL- in the Java window. (Note: CTRL- may not be mapped to kill -QUIT on all setups.) Doing this reveals two possibly unexpected threads:

  • AWT-EventQueue-0
  • AWT-Windows/AWT-Motif

Both are non-daemon threads and therefore cause the Java virtual machine to stay alive. Creating the Toolkit caused the appropriate threads for dealing with native windows and user input to be created. Once created, they won’t end on their own.

Is this correct? Some would argue that these threads should be created as daemon threads. But it isn’t that simple. Many applications simply create and show a GUI in main and they wouldn’t expect the program to end at this point. Could the AWT somehow be more intelligent, e.g., able to consider when there are no longer any visible frames? Possibly, but this is a complicated issue to deal with generically, and that isn’t how Sun decided to implement it. Therefore, once the AWT threads are started, you must call System.exit to end the program when appropriate for the given application.

On a side note, System.exit doesn’t work on applets, and calling it will cause a SecurityException to be thrown. The lifecycle of an applet is handled by the browser and may vary slightly in different implementations.

Random Walk Computing is the largest Java/CORBA consulting boutique in New York, focusing on solutions for the financial enterprise. Known for their leading-edge Java expertise, Random Walk consultants publish and speak about Java in some of the most respected forums in the world.