diff --git a/src/share/classes/javax/swing/JApplet.java b/src/share/classes/javax/swing/JApplet.java index b9b5b2506b9115ef58712cfd623ffd14c8129134..47f792a942d33a67cf754fc3a30c410da4541abd 100644 --- a/src/share/classes/javax/swing/JApplet.java +++ b/src/share/classes/javax/swing/JApplet.java @@ -131,10 +131,7 @@ public class JApplet extends Applet implements Accessible, // Check the timerQ and restart if necessary. TimerQueue q = TimerQueue.sharedInstance(); if(q != null) { - synchronized(q) { - if(!q.running) - q.start(); - } + q.startIfNeeded(); } /* Workaround for bug 4155072. The shared double buffer image diff --git a/src/share/classes/javax/swing/TimerQueue.java b/src/share/classes/javax/swing/TimerQueue.java index 2121939011f88fdddcbf6b8a826abf6553d1d900..1f694d1c82039fb1bbc2b0d89be7f2c500c8400b 100644 --- a/src/share/classes/javax/swing/TimerQueue.java +++ b/src/share/classes/javax/swing/TimerQueue.java @@ -31,6 +31,7 @@ package javax.swing; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.locks.*; import java.util.concurrent.atomic.AtomicLong; import sun.awt.AppContext; @@ -52,7 +53,8 @@ class TimerQueue implements Runnable new StringBuffer("TimerQueue.expiredTimersKey"); private final DelayQueue queue; - volatile boolean running; + private volatile boolean running; + private final Lock runningLock; /* Lock object used in place of class object for synchronization. * (4187686) @@ -69,7 +71,8 @@ class TimerQueue implements Runnable super(); queue = new DelayQueue(); // Now start the TimerQueue thread. - start(); + runningLock = new ReentrantLock(); + startIfNeeded(); } @@ -87,33 +90,30 @@ class TimerQueue implements Runnable } - synchronized void start() { - if (running) { - throw new RuntimeException("Can't start a TimerQueue " + - "that is already running"); - } - else { - final ThreadGroup threadGroup = - AppContext.getAppContext().getThreadGroup(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - Thread timerThread = new Thread(threadGroup, TimerQueue.this, - "TimerQueue"); - timerThread.setDaemon(true); - timerThread.setPriority(Thread.NORM_PRIORITY); - timerThread.start(); - return null; - } - }); - running = true; + void startIfNeeded() { + if (! running) { + runningLock.lock(); + try { + final ThreadGroup threadGroup = + AppContext.getAppContext().getThreadGroup(); + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Object run() { + Thread timerThread = new Thread(threadGroup, TimerQueue.this, + "TimerQueue"); + timerThread.setDaemon(true); + timerThread.setPriority(Thread.NORM_PRIORITY); + timerThread.start(); + return null; + } + }); + running = true; + } finally { + runningLock.unlock(); + } } } - synchronized void stop() { - running = false; - } - void addTimer(Timer timer, long delayMillis) { timer.getLock().lock(); try { @@ -164,6 +164,7 @@ class TimerQueue implements Runnable public void run() { + runningLock.lock(); try { while (running) { try { @@ -195,14 +196,14 @@ class TimerQueue implements Runnable } } catch (ThreadDeath td) { - synchronized (this) { - running = false; - // Mark all the timers we contain as not being queued. - for (DelayedTimer delayedTimer : queue) { - delayedTimer.getTimer().cancelEvent(); - } - throw td; + // Mark all the timers we contain as not being queued. + for (DelayedTimer delayedTimer : queue) { + delayedTimer.getTimer().cancelEvent(); } + throw td; + } finally { + running = false; + runningLock.unlock(); } }