jdk/src/share/classes/javax/swing/TimerQueue.java
changeset 1273 3b2eba521268
parent 2 90ce3da70b43
child 1301 15e81207e1f2
equal deleted inserted replaced
1272:40d9533e1505 1273:3b2eba521268
    29 
    29 
    30 
    30 
    31 
    31 
    32 import java.util.*;
    32 import java.util.*;
    33 import java.util.concurrent.*;
    33 import java.util.concurrent.*;
       
    34 import java.util.concurrent.locks.*;
    34 import java.util.concurrent.atomic.AtomicLong;
    35 import java.util.concurrent.atomic.AtomicLong;
    35 import sun.awt.AppContext;
    36 import sun.awt.AppContext;
    36 
    37 
    37 
    38 
    38 
    39 
    50         new StringBuffer("TimerQueue.sharedInstanceKey");
    51         new StringBuffer("TimerQueue.sharedInstanceKey");
    51     private static final Object expiredTimersKey =
    52     private static final Object expiredTimersKey =
    52         new StringBuffer("TimerQueue.expiredTimersKey");
    53         new StringBuffer("TimerQueue.expiredTimersKey");
    53 
    54 
    54     private final DelayQueue<DelayedTimer> queue;
    55     private final DelayQueue<DelayedTimer> queue;
    55     volatile boolean running;
    56     private volatile boolean running;
       
    57     private final Lock runningLock;
    56 
    58 
    57     /* Lock object used in place of class object for synchronization.
    59     /* Lock object used in place of class object for synchronization.
    58      * (4187686)
    60      * (4187686)
    59      */
    61      */
    60     private static final Object classLock = new Object();
    62     private static final Object classLock = new Object();
    67      */
    69      */
    68     public TimerQueue() {
    70     public TimerQueue() {
    69         super();
    71         super();
    70         queue = new DelayQueue<DelayedTimer>();
    72         queue = new DelayQueue<DelayedTimer>();
    71         // Now start the TimerQueue thread.
    73         // Now start the TimerQueue thread.
    72         start();
    74         runningLock = new ReentrantLock();
       
    75         startIfNeeded();
    73     }
    76     }
    74 
    77 
    75 
    78 
    76     public static TimerQueue sharedInstance() {
    79     public static TimerQueue sharedInstance() {
    77         synchronized (classLock) {
    80         synchronized (classLock) {
    85             return sharedInst;
    88             return sharedInst;
    86         }
    89         }
    87     }
    90     }
    88 
    91 
    89 
    92 
    90     synchronized void start() {
    93     void startIfNeeded() {
    91         if (running) {
    94         if (! running) {
    92             throw new RuntimeException("Can't start a TimerQueue " +
    95             runningLock.lock();
    93                                        "that is already running");
    96             try {
    94         }
    97                 final ThreadGroup threadGroup =
    95         else {
    98                     AppContext.getAppContext().getThreadGroup();
    96             final ThreadGroup threadGroup =
    99                 java.security.AccessController.doPrivileged(
    97                 AppContext.getAppContext().getThreadGroup();
   100                     new java.security.PrivilegedAction() {
    98             java.security.AccessController.doPrivileged(
   101                     public Object run() {
    99                 new java.security.PrivilegedAction() {
   102                         Thread timerThread = new Thread(threadGroup, TimerQueue.this,
   100                 public Object run() {
   103                                                         "TimerQueue");
   101                     Thread timerThread = new Thread(threadGroup, TimerQueue.this,
   104                         timerThread.setDaemon(true);
   102                                                     "TimerQueue");
   105                         timerThread.setPriority(Thread.NORM_PRIORITY);
   103                     timerThread.setDaemon(true);
   106                         timerThread.start();
   104                     timerThread.setPriority(Thread.NORM_PRIORITY);
   107                         return null;
   105                     timerThread.start();
   108                     }
   106                     return null;
   109                 });
   107                 }
   110                 running = true;
   108             });
   111             } finally {
   109             running = true;
   112                 runningLock.unlock();
   110         }
   113             }
   111     }
   114         }
   112 
   115     }
   113      synchronized void stop() {
       
   114          running = false;
       
   115      }
       
   116 
   116 
   117     void addTimer(Timer timer, long delayMillis) {
   117     void addTimer(Timer timer, long delayMillis) {
   118         timer.getLock().lock();
   118         timer.getLock().lock();
   119         try {
   119         try {
   120             // If the Timer is already in the queue, then ignore the add.
   120             // If the Timer is already in the queue, then ignore the add.
   162         }
   162         }
   163     }
   163     }
   164 
   164 
   165 
   165 
   166     public void run() {
   166     public void run() {
       
   167         runningLock.lock();
   167         try {
   168         try {
   168             while (running) {
   169             while (running) {
   169                 try {
   170                 try {
   170                     Timer timer = queue.take().getTimer();
   171                     Timer timer = queue.take().getTimer();
   171                     timer.getLock().lock();
   172                     timer.getLock().lock();
   193                 } catch (InterruptedException ignore) {
   194                 } catch (InterruptedException ignore) {
   194                 }
   195                 }
   195             }
   196             }
   196         }
   197         }
   197         catch (ThreadDeath td) {
   198         catch (ThreadDeath td) {
   198             synchronized (this) {
   199             // Mark all the timers we contain as not being queued.
   199                 running = false;
   200             for (DelayedTimer delayedTimer : queue) {
   200                 // Mark all the timers we contain as not being queued.
   201                 delayedTimer.getTimer().cancelEvent();
   201                 for (DelayedTimer delayedTimer : queue) {
   202             }
   202                     delayedTimer.getTimer().cancelEvent();
   203             throw td;
   203                 }
   204         } finally {
   204                 throw td;
   205             running = false;
   205             }
   206             runningLock.unlock();
   206         }
   207         }
   207     }
   208     }
   208 
   209 
   209 
   210 
   210     public String toString() {
   211     public String toString() {