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