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
27
28 package javax.swing;
29
30
31
32 import java.security.AccessController;
33 import java.security.PrivilegedAction;
34 import java.util.*;
35 import java.util.concurrent.*;
36 import java.util.concurrent.locks.*;
37 import java.util.concurrent.atomic.AtomicLong;
38 import sun.awt.AppContext;
39 import sun.misc.ManagedLocalsThread;
40
41 /**
42 * Internal class to manage all Timers using one thread.
43 * TimerQueue manages a queue of Timers. The Timers are chained
44 * together in a linked list sorted by the order in which they will expire.
45 *
46 * @author Dave Moore
47 * @author Igor Kushnirskiy
48 */
49 class TimerQueue implements Runnable
50 {
51 private static final Object sharedInstanceKey =
52 new StringBuffer("TimerQueue.sharedInstanceKey");
53 private static final Object expiredTimersKey =
54 new StringBuffer("TimerQueue.expiredTimersKey");
55
56 private final DelayQueue<DelayedTimer> queue;
57 private volatile boolean running;
58 private final Lock runningLock;
59
84 sharedInstanceKey);
85 if (sharedInst == null) {
86 sharedInst = new TimerQueue();
87 SwingUtilities.appContextPut(sharedInstanceKey, sharedInst);
88 }
89 return sharedInst;
90 }
91 }
92
93
94 void startIfNeeded() {
95 if (! running) {
96 runningLock.lock();
97 if (running) {
98 return;
99 }
100 try {
101 final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup();
102 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
103 String name = "TimerQueue";
104 Thread timerThread = new ManagedLocalsThread(threadGroup,
105 this, name);
106 timerThread.setDaemon(true);
107 timerThread.setPriority(Thread.NORM_PRIORITY);
108 timerThread.start();
109 return null;
110 });
111 running = true;
112 } finally {
113 runningLock.unlock();
114 }
115 }
116 }
117
118 void addTimer(Timer timer, long delayMillis) {
119 timer.getLock().lock();
120 try {
121 // If the Timer is already in the queue, then ignore the add.
122 if (! containsTimer(timer)) {
123 addTimer(new DelayedTimer(timer,
124 TimeUnit.MILLISECONDS.toNanos(delayMillis)
125 + now()));
|
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
27
28 package javax.swing;
29
30
31
32 import java.security.AccessController;
33 import java.security.PrivilegedAction;
34 import java.util.*;
35 import java.util.concurrent.*;
36 import java.util.concurrent.locks.*;
37 import java.util.concurrent.atomic.AtomicLong;
38 import sun.awt.AppContext;
39
40 /**
41 * Internal class to manage all Timers using one thread.
42 * TimerQueue manages a queue of Timers. The Timers are chained
43 * together in a linked list sorted by the order in which they will expire.
44 *
45 * @author Dave Moore
46 * @author Igor Kushnirskiy
47 */
48 class TimerQueue implements Runnable
49 {
50 private static final Object sharedInstanceKey =
51 new StringBuffer("TimerQueue.sharedInstanceKey");
52 private static final Object expiredTimersKey =
53 new StringBuffer("TimerQueue.expiredTimersKey");
54
55 private final DelayQueue<DelayedTimer> queue;
56 private volatile boolean running;
57 private final Lock runningLock;
58
83 sharedInstanceKey);
84 if (sharedInst == null) {
85 sharedInst = new TimerQueue();
86 SwingUtilities.appContextPut(sharedInstanceKey, sharedInst);
87 }
88 return sharedInst;
89 }
90 }
91
92
93 void startIfNeeded() {
94 if (! running) {
95 runningLock.lock();
96 if (running) {
97 return;
98 }
99 try {
100 final ThreadGroup threadGroup = AppContext.getAppContext().getThreadGroup();
101 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
102 String name = "TimerQueue";
103 Thread timerThread =
104 new Thread(threadGroup, this, name, 0, false);
105 timerThread.setDaemon(true);
106 timerThread.setPriority(Thread.NORM_PRIORITY);
107 timerThread.start();
108 return null;
109 });
110 running = true;
111 } finally {
112 runningLock.unlock();
113 }
114 }
115 }
116
117 void addTimer(Timer timer, long delayMillis) {
118 timer.getLock().lock();
119 try {
120 // If the Timer is already in the queue, then ignore the add.
121 if (! containsTimer(timer)) {
122 addTimer(new DelayedTimer(timer,
123 TimeUnit.MILLISECONDS.toNanos(delayMillis)
124 + now()));
|