OpenJDK / jdk8u / jdk8u / jdk
changeset 597:fc09152d5cf6
6623943: javax.swing.TimerQueue's thread occasionally fails to start
Reviewed-by: alexp
author | idk |
---|---|
date | Mon, 23 Jun 2008 15:21:37 -0400 |
parents | fa7147a26cd2 |
children | 282c86389114 |
files | src/share/classes/javax/swing/JApplet.java src/share/classes/javax/swing/TimerQueue.java |
diffstat | 2 files changed, 35 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/javax/swing/JApplet.java Thu Jun 19 18:03:43 2008 +0400 +++ b/src/share/classes/javax/swing/JApplet.java Mon Jun 23 15:21:37 2008 -0400 @@ -131,10 +131,7 @@ // 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
--- a/src/share/classes/javax/swing/TimerQueue.java Thu Jun 19 18:03:43 2008 +0400 +++ b/src/share/classes/javax/swing/TimerQueue.java Mon Jun 23 15:21:37 2008 -0400 @@ -31,6 +31,7 @@ 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 @@ new StringBuffer("TimerQueue.expiredTimersKey"); private final DelayQueue<DelayedTimer> 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 @@ super(); queue = new DelayQueue<DelayedTimer>(); // Now start the TimerQueue thread. - start(); + runningLock = new ReentrantLock(); + startIfNeeded(); } @@ -87,33 +90,30 @@ } - 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 @@ public void run() { + runningLock.lock(); try { while (running) { try { @@ -195,14 +196,14 @@ } } 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(); } }