Showing the changes to java/pkg/java/awt/doc-files/AWTThreadIssues.html (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,189 @@ | ||
| 1 | +<!-- | |
| 2 | + Copyright (c) 2002, 2006, 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 | +<html> | |
| 27 | +<body bgcolor=white> | |
| 28 | + | |
| 29 | +<h1 align=center>AWT Threading Issues</h1> | |
| 30 | + | |
| 31 | +<a name="ListenersThreads"></a> | |
| 32 | +<h2>Listeners and threads</h2> | |
| 33 | + | |
| 34 | +Unless otherwise noted all AWT listeners are notified on the event | |
| 35 | +dispatch thread. It is safe to remove/add listeners from any thread | |
| 36 | +during dispatching, but the changes only effect subsequent notification. | |
| 37 | +<br>For example, if a key listeners is added from another key listener, the | |
| 38 | +newly added listener is only notified on subsequent key events. | |
| 39 | + | |
| 40 | +<a name="Autoshutdown"></a> | |
| 41 | +<h2>Auto-shutdown</h2> | |
| 42 | + | |
| 43 | +According to | |
| 44 | +<cite>The Java™ Virtual Machine Specification</cite>, | |
| 45 | +sections 2.17.9 and 2.19, | |
| 46 | +the Java virtual machine (JVM) initially starts up with a single non-daemon | |
| 47 | +thread, which typically calls the <code>main</code> method of some class. | |
| 48 | +The virtual machine terminates all its activity and exits when | |
| 49 | +one of two things happens: | |
| 50 | +<ul> | |
| 51 | + <li> All the threads that are not daemon threads terminate. | |
| 52 | + <li> Some thread invokes the <code>exit</code> method of class | |
| 53 | + <code>Runtime</code> or class <code>System</code>, and the exit | |
| 54 | + operation is permitted by the security manager. | |
| 55 | +</ul> | |
| 56 | +<p> | |
| 57 | +This implies that if an application doesn't start any threads itself, | |
| 58 | +the JVM will exit as soon as <code>main</code> terminates. | |
| 59 | +This is not the case, however, for a simple application | |
| 60 | +that creates and displays a <code>java.awt.Frame</code>: | |
| 61 | +<pre> | |
| 62 | + public static void main(String[] args) { | |
| 63 | + Frame frame = new Frame(); | |
| 64 | + frame.setVisible(true); | |
| 65 | + } | |
| 66 | +</pre> | |
| 67 | +The reason is that AWT encapsulates asynchronous event dispatch | |
| 68 | +machinery to process events AWT or Swing components can fire. The | |
| 69 | +exact behavior of this machinery is implementation-dependent. In | |
| 70 | +particular, it can start non-daemon helper threads for its internal | |
| 71 | +purposes. In fact, these are the threads that prevent the example | |
| 72 | +above from exiting. The only restrictions imposed on the behavior of | |
| 73 | +this machinery are as follows: | |
| 74 | +<ul> | |
| 75 | + <li> <a href="../EventQueue.html#isDispatchThread()"><code>EventQueue.isDispatchThread</code></a> | |
| 76 | + returns <code>true</code> if and only if the calling thread is the | |
| 77 | + event dispatch thread started by the machinery; | |
| 78 | + <li> <code>AWTEvents</code> which were actually enqueued to a | |
| 79 | + particular <code>EventQueue</code> (note that events being | |
| 80 | + posted to the <code>EventQueue</code> can be coalesced) are | |
| 81 | + dispatched: | |
| 82 | + <ul> | |
| 83 | + <li> Sequentially. | |
| 84 | + <dd> That is, it is not permitted that several events from | |
| 85 | + this queue are dispatched simultaneously. | |
| 86 | + <li> In the same order as they are enqueued. | |
| 87 | + <dd> That is, if <code>AWTEvent</code> A is enqueued | |
| 88 | + to the <code>EventQueue</code> before | |
| 89 | + <code>AWTEvent</code> B then event B will not be | |
| 90 | + dispatched before event A. | |
| 91 | + </ul> | |
| 92 | + <li> There is at least one alive non-daemon thread while there is at | |
| 93 | + least one displayable AWT or Swing component within the | |
| 94 | + application (see | |
| 95 | + <a href="../Component.html#isDisplayable()"><code>Component.isDisplayable</code></a>). | |
| 96 | +</ul> | |
| 97 | +The implications of the third restriction are as follows: | |
| 98 | +<ul> | |
| 99 | + <li> The JVM will exit if some thread invokes the <code>exit</code> | |
| 100 | + method of class <code>Runtime</code> or class <code>System</code> | |
| 101 | + regardless of the presence of displayable components; | |
| 102 | + <li> Even if the application terminates all non-daemon threads it | |
| 103 | + started, the JVM will not exit while there is at least one | |
| 104 | + displayable component. | |
| 105 | +</ul> | |
| 106 | +It depends on the implementation if and when the non-daemon helper | |
| 107 | +threads are terminated once all components are made undisplayable. | |
| 108 | +The implementation-specific details are given below. | |
| 109 | + | |
| 110 | +<h3> | |
| 111 | +Implementation-dependent behavior. | |
| 112 | +</h3> | |
| 113 | + | |
| 114 | +Prior to 1.4, the helper threads were never terminated. | |
| 115 | +<p> | |
| 116 | +Starting with 1.4, the behavior has changed as a result of the fix for | |
| 117 | +<a href="http://bugs.sun.com/view_bug.do?bug_id=4030718"> | |
| 118 | +4030718</a>. With the current implementation, AWT terminates all its | |
| 119 | +helper threads allowing the application to exit cleanly when the | |
| 120 | +following three conditions are true: | |
| 121 | +<ul> | |
| 122 | + <li> There are no displayable AWT or Swing components. | |
| 123 | + <li> There are no native events in the native event queue. | |
| 124 | + <li> There are no AWT events in java EventQueues. | |
| 125 | +</ul> | |
| 126 | +Therefore, a stand-alone AWT application that wishes to exit | |
| 127 | +cleanly without calling <code>System.exit</code> must: | |
| 128 | +<ul> | |
| 129 | + <li> Make sure that all AWT or Swing components are made | |
| 130 | + undisplayable when the application finishes. This can be done | |
| 131 | + by calling | |
| 132 | +<a href="../Window.html#dispose()"><code>Window.dispose</code></a> | |
| 133 | + on all top-level <code>Windows</code>. See | |
| 134 | +<a href="../Frame.html#getFrames()"><code>Frame.getFrames</code></a>. | |
| 135 | + <li> Make sure that no method of AWT event listeners registered by | |
| 136 | + the application with any AWT or Swing component can run into an | |
| 137 | + infinite loop or hang indefinitely. For example, an AWT listener | |
| 138 | + method triggered by some AWT event can post a new AWT event of | |
| 139 | + the same type to the <code>EventQueue</code>. | |
| 140 | + The argument is that methods | |
| 141 | + of AWT event listeners are typically executed on helper | |
| 142 | + threads. | |
| 143 | +</ul> | |
| 144 | +Note, that while an application following these recommendations will | |
| 145 | +exit cleanly under normal conditions, it is not guaranteed that it | |
| 146 | +will exit cleanly in all cases. Two examples: | |
| 147 | +<ul> | |
| 148 | + <li> Other packages can create displayable components for internal | |
| 149 | + needs and never make them undisplayable. See | |
| 150 | +<a href="http://bugs.sun.com/view_bug.do?bug_id=4515058"> | |
| 151 | +4515058</a>, | |
| 152 | +<a href="http://bugs.sun.com/view_bug.do?bug_id=4671025"> | |
| 153 | +4671025</a>, and | |
| 154 | +<a href="http://bugs.sun.com/view_bug.do?bug_id=4465537"> | |
| 155 | +4465537</a>. | |
| 156 | + <li> Both Microsoft Windows and X11 allow an application to send native | |
| 157 | + events to windows that belong to another application. With this | |
| 158 | + feature it is possible to write a malicious program that will | |
| 159 | + continuously send events to all available windows preventing | |
| 160 | + any AWT application from exiting cleanly. | |
| 161 | +</ul> | |
| 162 | +On the other hand, if you require the JVM to continue running even after | |
| 163 | +the application has made all components undisplayable you should start a | |
| 164 | +non-daemon thread that blocks forever. | |
| 165 | + | |
| 166 | +<pre> | |
| 167 | + <...> | |
| 168 | + Runnable r = new Runnable() { | |
| 169 | + public void run() { | |
| 170 | + Object o = new Object(); | |
| 171 | + try { | |
| 172 | + synchronized (o) { | |
| 173 | + o.wait(); | |
| 174 | + } | |
| 175 | + } catch (InterruptedException ie) { | |
| 176 | + } | |
| 177 | + } | |
| 178 | + }; | |
| 179 | + Thread t = new Thread(r); | |
| 180 | + t.setDaemon(false); | |
| 181 | + t.start(); | |
| 182 | + <...> | |
| 183 | +</pre> | |
| 184 | + | |
| 185 | +<cite>The Java™ Virtual Machine Specification</cite> | |
| 186 | + guarantees | |
| 187 | +that the JVM doesn't exit until this thread terminates. | |
| 188 | +</body> | |
| 189 | +</html> | |