Source Code Cross Referenced for AWTAutoShutdown.java in  » 6.0-JDK-Modules-sun » awt » sun » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » awt » sun.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package sun.awt;
027:
028:        import java.awt.AWTEvent;
029:        import java.util.Collections;
030:        import java.util.HashSet;
031:        import java.util.IdentityHashMap;
032:        import java.util.Map;
033:        import java.util.logging.Logger;
034:
035:        /**
036:         * This class is to let AWT shutdown automatically when a user is done 
037:         * with AWT. It tracks AWT state using the following parameters:  
038:         * <ul>
039:         * <li><code>peerMap</code> - the map between the existing peer objects
040:         *     and their associated targets
041:         * <li><code>toolkitThreadBusy</code> - whether the toolkit thread 
042:         *     is waiting for a new native event to appear in its queue 
043:         *     or is dispatching an event
044:         * <li><code>busyThreadSet</code> - a set of all the event dispatch 
045:         *     threads that are busy at this moment, i.e. those that are not 
046:         *     waiting for a new event to appear in their event queue.       
047:         * </ul><p>
048:         * AWT is considered to be in ready-to-shutdown state when  
049:         * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code> 
050:         * is false and <code>busyThreadSet</code> is empty. 
051:         * The internal AWTAutoShutdown logic secures that the single non-daemon
052:         * thread (<code>blockerThread</code>) is running when AWT is not in 
053:         * ready-to-shutdown state. This blocker thread is to prevent AWT from
054:         * exiting since the toolkit thread is now daemon and all the event 
055:         * dispatch threads are started only when needed. Once it is detected
056:         * that AWT is in ready-to-shutdown state this blocker thread waits
057:         * for a certain timeout and if AWT state doesn't change during timeout
058:         * this blocker thread terminates all the event dispatch threads and
059:         * exits.
060:         */
061:        public final class AWTAutoShutdown implements  Runnable {
062:
063:            private static final AWTAutoShutdown theInstance = new AWTAutoShutdown();
064:
065:            /**
066:             * This lock object is used to synchronize shutdown operations. 
067:             */
068:            private final Object mainLock = new Object();
069:
070:            /** 
071:             * This lock object is to secure that when a new blocker thread is 
072:             * started it will be the first who acquire the main lock after 
073:             * the thread that created the new blocker released the main lock
074:             * by calling lock.wait() to wait for the blocker to start. 
075:             */
076:            private final Object activationLock = new Object();
077:
078:            /** 
079:             * This set keeps references to all the event dispatch threads that
080:             * are busy at this moment, i.e. those that are not waiting for a
081:             * new event to appear in their event queue.       
082:             * Access is synchronized on the main lock object. 
083:             */
084:            private final HashSet busyThreadSet = new HashSet(7);
085:
086:            /** 
087:             * Indicates whether the toolkit thread is waiting for a new native
088:             * event to appear or is dispatching an event. 
089:             */
090:            private boolean toolkitThreadBusy = false;
091:
092:            /** 
093:             * This is a map between components and their peers.
094:             * we should work with in under activationLock&mainLock lock.
095:             */
096:            private final Map peerMap = new IdentityHashMap();
097:
098:            /** 
099:             * References the alive non-daemon thread that is currently used 
100:             * for keeping AWT from exiting. 
101:             */
102:            private Thread blockerThread = null;
103:
104:            /**
105:             * We need this flag to secure that AWT state hasn't changed while
106:             * we were waiting for the safety timeout to pass.
107:             */
108:            private boolean timeoutPassed = false;
109:
110:            /**
111:             * Once we detect that AWT is ready to shutdown we wait for a certain
112:             * timeout to pass before stopping event dispatch threads.
113:             */
114:            private static final int SAFETY_TIMEOUT = 1000;
115:
116:            /**
117:             * Constructor method is intentionally made private to secure 
118:             * a single instance. Use getInstance() to reference it.
119:             * 
120:             * @see     AWTAutoShutdown#getInstance
121:             */
122:            private AWTAutoShutdown() {
123:            }
124:
125:            /**
126:             * Returns reference to a single AWTAutoShutdown instance.
127:             */
128:            public static AWTAutoShutdown getInstance() {
129:                return theInstance;
130:            }
131:
132:            /**
133:             * Notify that the toolkit thread is not waiting for a native event
134:             * to appear in its queue. 
135:             *
136:             * @see     AWTAutoShutdown#notifyToolkitThreadFree
137:             * @see     AWTAutoShutdown#setToolkitBusy
138:             * @see     AWTAutoShutdown#isReadyToShutdown
139:             */
140:            public static void notifyToolkitThreadBusy() {
141:                getInstance().setToolkitBusy(true);
142:            }
143:
144:            /**
145:             * Notify that the toolkit thread is waiting for a native event
146:             * to appear in its queue. 
147:             *
148:             * @see     AWTAutoShutdown#notifyToolkitThreadFree
149:             * @see     AWTAutoShutdown#setToolkitBusy
150:             * @see     AWTAutoShutdown#isReadyToShutdown
151:             */
152:            public static void notifyToolkitThreadFree() {
153:                getInstance().setToolkitBusy(false);
154:            }
155:
156:            /**
157:             * Add a specified thread to the set of busy event dispatch threads.
158:             * If this set already contains the specified thread, the call leaves 
159:             * this set unchanged and returns silently.
160:             *
161:             * @param thread thread to be added to this set, if not present.
162:             * @see     AWTAutoShutdown#notifyThreadFree
163:             * @see     AWTAutoShutdown#isReadyToShutdown
164:             */
165:            public void notifyThreadBusy(final Thread thread) {
166:                synchronized (activationLock) {
167:                    synchronized (mainLock) {
168:                        if (blockerThread == null) {
169:                            activateBlockerThread();
170:                        } else if (isReadyToShutdown()) {
171:                            mainLock.notifyAll();
172:                            timeoutPassed = false;
173:                        }
174:                        busyThreadSet.add(thread);
175:                    }
176:                }
177:            }
178:
179:            /**
180:             * Remove a specified thread from the set of busy event dispatch threads.
181:             * If this set doesn't contain the specified thread, the call leaves 
182:             * this set unchanged and returns silently.
183:             *
184:             * @param thread thread to be removed from this set, if present.
185:             * @see     AWTAutoShutdown#notifyThreadBusy
186:             * @see     AWTAutoShutdown#isReadyToShutdown
187:             */
188:            public void notifyThreadFree(final Thread thread) {
189:                synchronized (activationLock) {
190:                    synchronized (mainLock) {
191:                        busyThreadSet.remove(thread);
192:                        if (isReadyToShutdown()) {
193:                            mainLock.notifyAll();
194:                            timeoutPassed = false;
195:                        }
196:                    }
197:                }
198:            }
199:
200:            /**
201:             * Notify that the peermap has been updated, that means a new peer 
202:             * has been created or some existing peer has been disposed.
203:             *
204:             * @see     AWTAutoShutdown#isReadyToShutdown
205:             */
206:            void notifyPeerMapUpdated() {
207:                synchronized (activationLock) {
208:                    synchronized (mainLock) {
209:                        if (!isReadyToShutdown() && blockerThread == null) {
210:                            activateBlockerThread();
211:                        } else {
212:                            mainLock.notifyAll();
213:                            timeoutPassed = false;
214:                        }
215:                    }
216:                }
217:            }
218:
219:            /**
220:             * Determine whether AWT is currently in ready-to-shutdown state.
221:             * AWT is considered to be in ready-to-shutdown state if 
222:             * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code> 
223:             * is false and <code>busyThreadSet</code> is empty. 
224:             *
225:             * @return true if AWT is in ready-to-shutdown state.
226:             */
227:            private boolean isReadyToShutdown() {
228:                return (!toolkitThreadBusy && peerMap.isEmpty() && busyThreadSet
229:                        .isEmpty());
230:            }
231:
232:            /**
233:             * Notify about the toolkit thread state change. 
234:             *
235:             * @param busy true if the toolkit thread state changes from idle
236:             *             to busy.
237:             * @see     AWTAutoShutdown#notifyToolkitThreadBusy
238:             * @see     AWTAutoShutdown#notifyToolkitThreadFree
239:             * @see     AWTAutoShutdown#isReadyToShutdown
240:             */
241:            private void setToolkitBusy(final boolean busy) {
242:                if (busy != toolkitThreadBusy) {
243:                    synchronized (activationLock) {
244:                        synchronized (mainLock) {
245:                            if (busy != toolkitThreadBusy) {
246:                                if (busy) {
247:                                    if (blockerThread == null) {
248:                                        activateBlockerThread();
249:                                    } else if (isReadyToShutdown()) {
250:                                        mainLock.notifyAll();
251:                                        timeoutPassed = false;
252:                                    }
253:                                    toolkitThreadBusy = busy;
254:                                } else {
255:                                    toolkitThreadBusy = busy;
256:                                    if (isReadyToShutdown()) {
257:                                        mainLock.notifyAll();
258:                                        timeoutPassed = false;
259:                                    }
260:                                }
261:                            }
262:                        }
263:                    }
264:                }
265:            }
266:
267:            /**
268:             * Implementation of the Runnable interface.
269:             * Incapsulates the blocker thread functionality. 
270:             *
271:             * @see     AWTAutoShutdown#isReadyToShutdown
272:             */
273:            public void run() {
274:                Thread currentThread = Thread.currentThread();
275:                boolean interrupted = false;
276:                synchronized (mainLock) {
277:                    try {
278:                        /* Notify that the thread is started. */
279:                        mainLock.notifyAll();
280:                        while (blockerThread == currentThread) {
281:                            mainLock.wait();
282:                            timeoutPassed = false;
283:                            /*
284:                             * This loop is introduced to handle the following case:
285:                             * it is possible that while we are waiting for the 
286:                             * safety timeout to pass AWT state can change to 
287:                             * not-ready-to-shutdown and back to ready-to-shutdown.
288:                             * In this case we have to wait once again.
289:                             * NOTE: we shouldn't break into the outer loop 
290:                             * in this case, since we may never be notified 
291:                             * in an outer infinite wait at this point.
292:                             */
293:                            while (isReadyToShutdown()) {
294:                                if (timeoutPassed) {
295:                                    timeoutPassed = false;
296:                                    blockerThread = null;
297:                                    break;
298:                                }
299:                                timeoutPassed = true;
300:                                mainLock.wait(SAFETY_TIMEOUT);
301:                            }
302:                        }
303:                    } catch (InterruptedException e) {
304:                        interrupted = true;
305:                    } finally {
306:                        if (blockerThread == currentThread) {
307:                            blockerThread = null;
308:                        }
309:                    }
310:                }
311:                if (!interrupted) {
312:                    AppContext.stopEventDispatchThreads();
313:                }
314:            }
315:
316:            static AWTEvent getShutdownEvent() {
317:                return new AWTEvent(getInstance(), 0) {
318:                };
319:            }
320:
321:            /**
322:             * Creates and starts a new blocker thread. Doesn't return until
323:             * the new blocker thread starts.
324:             */
325:            private void activateBlockerThread() {
326:                Thread thread = new Thread(this , "AWT-Shutdown");
327:                thread.setDaemon(false);
328:                blockerThread = thread;
329:                thread.start();
330:                try {
331:                    /* Wait for the blocker thread to start. */
332:                    mainLock.wait();
333:                } catch (InterruptedException e) {
334:                    System.err.println("AWT blocker activation interrupted:");
335:                    e.printStackTrace();
336:                }
337:            }
338:
339:            final void registerPeer(final Object target, final Object peer) {
340:                synchronized (activationLock) {
341:                    synchronized (mainLock) {
342:                        peerMap.put(target, peer);
343:                        notifyPeerMapUpdated();
344:                    }
345:                }
346:            }
347:
348:            final void unregisterPeer(final Object target, final Object peer) {
349:                synchronized (activationLock) {
350:                    synchronized (mainLock) {
351:                        if (peerMap.get(target) == peer) {
352:                            peerMap.remove(target);
353:                            notifyPeerMapUpdated();
354:                        }
355:                    }
356:                }
357:            }
358:
359:            final Object getPeer(final Object target) {
360:                synchronized (activationLock) {
361:                    synchronized (mainLock) {
362:                        return peerMap.get(target);
363:                    }
364:                }
365:            }
366:
367:            final void dumpPeers(final Logger aLog) {
368:                synchronized (activationLock) {
369:                    synchronized (mainLock) {
370:                        aLog.fine("Mapped peers:");
371:                        for (Object key : peerMap.keySet()) {
372:                            aLog.fine(key + "->" + peerMap.get(key));
373:                        }
374:                    }
375:                }
376:            }
377:
378:        } // class AWTAutoShutdown
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.