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> | ||