< prev index next >

src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java

Print this page




  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.AWTEvent;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.HashSet;
  32 import java.util.IdentityHashMap;
  33 import java.util.Map;
  34 import java.util.Set;
  35 
  36 import sun.awt.util.ThreadGroupUtils;
  37 import sun.misc.ManagedLocalsThread;
  38 import sun.util.logging.PlatformLogger;
  39 
  40 /**
  41  * This class is to let AWT shutdown automatically when a user is done
  42  * with AWT. It tracks AWT state using the following parameters:
  43  * <ul>
  44  * <li><code>peerMap</code> - the map between the existing peer objects
  45  *     and their associated targets
  46  * <li><code>toolkitThreadBusy</code> - whether the toolkit thread
  47  *     is waiting for a new native event to appear in its queue
  48  *     or is dispatching an event
  49  * <li><code>busyThreadSet</code> - a set of all the event dispatch
  50  *     threads that are busy at this moment, i.e. those that are not
  51  *     waiting for a new event to appear in their event queue.
  52  * </ul><p>
  53  * AWT is considered to be in ready-to-shutdown state when
  54  * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
  55  * is false and <code>busyThreadSet</code> is empty.
  56  * The internal AWTAutoShutdown logic secures that the single non-daemon
  57  * thread (<code>blockerThread</code>) is running when AWT is not in
  58  * ready-to-shutdown state. This blocker thread is to prevent AWT from
  59  * exiting since the toolkit thread is now daemon and all the event
  60  * dispatch threads are started only when needed. Once it is detected
  61  * that AWT is in ready-to-shutdown state this blocker thread waits
  62  * for a certain timeout and if AWT state doesn't change during timeout
  63  * this blocker thread terminates all the event dispatch threads and
  64  * exits.
  65  */
  66 public final class AWTAutoShutdown implements Runnable {
  67 
  68     private static final AWTAutoShutdown theInstance = new AWTAutoShutdown();
  69 
  70     /**
  71      * This lock object is used to synchronize shutdown operations.
  72      */
  73     private final Object mainLock = new Object();
  74 
  75     /**
  76      * This lock object is to secure that when a new blocker thread is
  77      * started it will be the first who acquire the main lock after


 212      * has been created or some existing peer has been disposed.
 213      *
 214      * @see     AWTAutoShutdown#isReadyToShutdown
 215      */
 216     void notifyPeerMapUpdated() {
 217         synchronized (activationLock) {
 218             synchronized (mainLock) {
 219                 if (!isReadyToShutdown() && blockerThread == null) {
 220                     activateBlockerThread();
 221                 } else {
 222                     mainLock.notifyAll();
 223                     timeoutPassed = false;
 224                 }
 225             }
 226         }
 227     }
 228 
 229     /**
 230      * Determine whether AWT is currently in ready-to-shutdown state.
 231      * AWT is considered to be in ready-to-shutdown state if
 232      * <code>peerMap</code> is empty and <code>toolkitThreadBusy</code>
 233      * is false and <code>busyThreadSet</code> is empty.
 234      *
 235      * @return true if AWT is in ready-to-shutdown state.
 236      */
 237     private boolean isReadyToShutdown() {
 238         return (!toolkitThreadBusy &&
 239                  peerMap.isEmpty() &&
 240                  busyThreadSet.isEmpty());
 241     }
 242 
 243     /**
 244      * Notify about the toolkit thread state change.
 245      *
 246      * @param busy true if the toolkit thread state changes from idle
 247      *             to busy.
 248      * @see     AWTAutoShutdown#notifyToolkitThreadBusy
 249      * @see     AWTAutoShutdown#notifyToolkitThreadFree
 250      * @see     AWTAutoShutdown#isReadyToShutdown
 251      */
 252     private void setToolkitBusy(final boolean busy) {
 253         if (busy != toolkitThreadBusy) {




  24  */
  25 
  26 package sun.awt;
  27 
  28 import java.awt.AWTEvent;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.HashSet;
  32 import java.util.IdentityHashMap;
  33 import java.util.Map;
  34 import java.util.Set;
  35 
  36 import sun.awt.util.ThreadGroupUtils;
  37 import sun.misc.ManagedLocalsThread;
  38 import sun.util.logging.PlatformLogger;
  39 
  40 /**
  41  * This class is to let AWT shutdown automatically when a user is done
  42  * with AWT. It tracks AWT state using the following parameters:
  43  * <ul>
  44  * <li>{@code peerMap} - the map between the existing peer objects
  45  *     and their associated targets
  46  * <li>{@code toolkitThreadBusy} - whether the toolkit thread
  47  *     is waiting for a new native event to appear in its queue
  48  *     or is dispatching an event
  49  * <li>{@code busyThreadSet} - a set of all the event dispatch
  50  *     threads that are busy at this moment, i.e. those that are not
  51  *     waiting for a new event to appear in their event queue.
  52  * </ul><p>
  53  * AWT is considered to be in ready-to-shutdown state when
  54  * {@code peerMap} is empty and {@code toolkitThreadBusy}
  55  * is false and {@code busyThreadSet} is empty.
  56  * The internal AWTAutoShutdown logic secures that the single non-daemon
  57  * thread ({@code blockerThread}) is running when AWT is not in
  58  * ready-to-shutdown state. This blocker thread is to prevent AWT from
  59  * exiting since the toolkit thread is now daemon and all the event
  60  * dispatch threads are started only when needed. Once it is detected
  61  * that AWT is in ready-to-shutdown state this blocker thread waits
  62  * for a certain timeout and if AWT state doesn't change during timeout
  63  * this blocker thread terminates all the event dispatch threads and
  64  * exits.
  65  */
  66 public final class AWTAutoShutdown implements Runnable {
  67 
  68     private static final AWTAutoShutdown theInstance = new AWTAutoShutdown();
  69 
  70     /**
  71      * This lock object is used to synchronize shutdown operations.
  72      */
  73     private final Object mainLock = new Object();
  74 
  75     /**
  76      * This lock object is to secure that when a new blocker thread is
  77      * started it will be the first who acquire the main lock after


 212      * has been created or some existing peer has been disposed.
 213      *
 214      * @see     AWTAutoShutdown#isReadyToShutdown
 215      */
 216     void notifyPeerMapUpdated() {
 217         synchronized (activationLock) {
 218             synchronized (mainLock) {
 219                 if (!isReadyToShutdown() && blockerThread == null) {
 220                     activateBlockerThread();
 221                 } else {
 222                     mainLock.notifyAll();
 223                     timeoutPassed = false;
 224                 }
 225             }
 226         }
 227     }
 228 
 229     /**
 230      * Determine whether AWT is currently in ready-to-shutdown state.
 231      * AWT is considered to be in ready-to-shutdown state if
 232      * {@code peerMap} is empty and {@code toolkitThreadBusy}
 233      * is false and {@code busyThreadSet} is empty.
 234      *
 235      * @return true if AWT is in ready-to-shutdown state.
 236      */
 237     private boolean isReadyToShutdown() {
 238         return (!toolkitThreadBusy &&
 239                  peerMap.isEmpty() &&
 240                  busyThreadSet.isEmpty());
 241     }
 242 
 243     /**
 244      * Notify about the toolkit thread state change.
 245      *
 246      * @param busy true if the toolkit thread state changes from idle
 247      *             to busy.
 248      * @see     AWTAutoShutdown#notifyToolkitThreadBusy
 249      * @see     AWTAutoShutdown#notifyToolkitThreadFree
 250      * @see     AWTAutoShutdown#isReadyToShutdown
 251      */
 252     private void setToolkitBusy(final boolean busy) {
 253         if (busy != toolkitThreadBusy) {


< prev index next >