1 <!--
2 Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 This code is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License version 2 only, as
7 published by the Free Software Foundation. Oracle designates this
8 particular file as subject to the "Classpath" exception as provided
9 by Oracle in the LICENSE file that accompanied this code.
10
11 This code is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 version 2 for more details (a copy is included in the LICENSE file that
15 accompanied this code).
16
17 You should have received a copy of the GNU General Public License version
18 2 along with this work; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 or visit www.oracle.com if you need additional information or have any
23 questions.
24 -->
25
26 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
27 <html>
28 <head>
29 <title></title>
30 </head>
31 <body bgcolor=white>
32
33 <h1 align=center>AWT Threading Issues</h1>
34
35 <a name="ListenersThreads"></a>
36 <h2>Listeners and threads</h2>
37
38 Unless otherwise noted all AWT listeners are notified on the event
39 dispatch thread. It is safe to remove/add listeners from any thread
40 during dispatching, but the changes only effect subsequent notification.
41 <br>For example, if a key listeners is added from another key listener, the
42 newly added listener is only notified on subsequent key events.
43
44 <a name="Autoshutdown"></a>
45 <h2>Auto-shutdown</h2>
46
47 According to
48 <cite>The Java™ Virtual Machine Specification</cite>,
49 sections 2.17.9 and 2.19,
50 the Java virtual machine (JVM) initially starts up with a single non-daemon
51 thread, which typically calls the <code>main</code> method of some class.
52 The virtual machine terminates all its activity and exits when
53 one of two things happens:
54 <ul>
55 <li> All the threads that are not daemon threads terminate.
56 <li> Some thread invokes the <code>exit</code> method of class
57 <code>Runtime</code> or class <code>System</code>, and the exit
58 operation is permitted by the security manager.
59 </ul>
60 <p>
61 This implies that if an application doesn't start any threads itself,
62 the JVM will exit as soon as <code>main</code> terminates.
63 This is not the case, however, for a simple application
64 that creates and displays a <code>java.awt.Frame</code>:
65 <pre>
66 public static void main(String[] args) {
67 Frame frame = new Frame();
68 frame.setVisible(true);
69 }
70 </pre>
71 The reason is that AWT encapsulates asynchronous event dispatch
72 machinery to process events AWT or Swing components can fire. The
73 exact behavior of this machinery is implementation-dependent. In
74 particular, it can start non-daemon helper threads for its internal
75 purposes. In fact, these are the threads that prevent the example
76 above from exiting. The only restrictions imposed on the behavior of
77 this machinery are as follows:
78 <ul>
79 <li> <a href="../EventQueue.html#isDispatchThread()"><code>EventQueue.isDispatchThread</code></a>
80 returns <code>true</code> if and only if the calling thread is the
81 event dispatch thread started by the machinery;
82 <li> <code>AWTEvents</code> which were actually enqueued to a
83 particular <code>EventQueue</code> (note that events being
84 posted to the <code>EventQueue</code> can be coalesced) are
85 dispatched:
86 <ul>
87 <li> Sequentially.
88 <dl><dd> That is, it is not permitted that several events from
89 this queue are dispatched simultaneously. </dd></dl>
90 <li> In the same order as they are enqueued.
91 <dl><dd> That is, if <code>AWTEvent</code> A is enqueued
92 to the <code>EventQueue</code> before
93 <code>AWTEvent</code> B then event B will not be
94 dispatched before event A.</dd></dl>
95 </ul>
96 <li> There is at least one alive non-daemon thread while there is at
97 least one displayable AWT or Swing component within the
98 application (see
99 <a href="../Component.html#isDisplayable()"><code>Component.isDisplayable</code></a>).
100 </ul>
101 The implications of the third restriction are as follows:
102 <ul>
103 <li> The JVM will exit if some thread invokes the <code>exit</code>
104 method of class <code>Runtime</code> or class <code>System</code>
105 regardless of the presence of displayable components;
106 <li> Even if the application terminates all non-daemon threads it
107 started, the JVM will not exit while there is at least one
108 displayable component.
109 </ul>
110 It depends on the implementation if and when the non-daemon helper
111 threads are terminated once all components are made undisplayable.
112 The implementation-specific details are given below.
113
114 <h3>
115 Implementation-dependent behavior.
116 </h3>
117
118 Prior to 1.4, the helper threads were never terminated.
119 <p>
120 Starting with 1.4, the behavior has changed as a result of the fix for
121 <a href="http://bugs.sun.com/view_bug.do?bug_id=4030718">
122 4030718</a>. With the current implementation, AWT terminates all its
123 helper threads allowing the application to exit cleanly when the
124 following three conditions are true:
125 <ul>
126 <li> There are no displayable AWT or Swing components.
127 <li> There are no native events in the native event queue.
128 <li> There are no AWT events in java EventQueues.
129 </ul>
130 Therefore, a stand-alone AWT application that wishes to exit
131 cleanly without calling <code>System.exit</code> must:
132 <ul>
133 <li> Make sure that all AWT or Swing components are made
134 undisplayable when the application finishes. This can be done
135 by calling
136 <a href="../Window.html#dispose()"><code>Window.dispose</code></a>
137 on all top-level <code>Windows</code>. See
138 <a href="../Frame.html#getFrames()"><code>Frame.getFrames</code></a>.
139 <li> Make sure that no method of AWT event listeners registered by
140 the application with any AWT or Swing component can run into an
141 infinite loop or hang indefinitely. For example, an AWT listener
142 method triggered by some AWT event can post a new AWT event of
143 the same type to the <code>EventQueue</code>.
144 The argument is that methods
145 of AWT event listeners are typically executed on helper
146 threads.
147 </ul>
148 Note, that while an application following these recommendations will
149 exit cleanly under normal conditions, it is not guaranteed that it
150 will exit cleanly in all cases. Two examples:
151 <ul>
152 <li> Other packages can create displayable components for internal
153 needs and never make them undisplayable. See
154 <a href="http://bugs.sun.com/view_bug.do?bug_id=4515058">
155 4515058</a>,
156 <a href="http://bugs.sun.com/view_bug.do?bug_id=4671025">
157 4671025</a>, and
158 <a href="http://bugs.sun.com/view_bug.do?bug_id=4465537">
159 4465537</a>.
160 <li> Both Microsoft Windows and X11 allow an application to send native
161 events to windows that belong to another application. With this
162 feature it is possible to write a malicious program that will
163 continuously send events to all available windows preventing
164 any AWT application from exiting cleanly.
165 </ul>
166 On the other hand, if you require the JVM to continue running even after
167 the application has made all components undisplayable you should start a
168 non-daemon thread that blocks forever.
169
170 <pre>
171 <...>
172 Runnable r = new Runnable() {
173 public void run() {
174 Object o = new Object();
175 try {
176 synchronized (o) {
177 o.wait();
178 }
179 } catch (InterruptedException ie) {
180 }
181 }
182 };
183 Thread t = new Thread(r);
184 t.setDaemon(false);
185 t.start();
186 <...>
187 </pre>
188
189 <cite>The Java™ Virtual Machine Specification</cite>
190 guarantees
191 that the JVM doesn't exit until this thread terminates.
192 </body>
193 </html>