<Swing Dev> Problem in Swing Timer

Igor Kushnirskiy Igor.Kushnirskiy at Sun.COM
Wed Dec 3 17:16:51 UTC 2008


Hi Roman,

There was a bug which covered this problem - 6623943 
[javax.swing.TimerQueue's thread occasionally fails to start] 
http://bugs.sun.com/view_bug.do?bug_id=6623943.
It was fixed in the jdk7 b38:
changeset fc09152d5cf6
http://hg.openjdk.java.net/jdk7/swing/jdk/rev/fc09152d5cf6

The fix has not been backported to 6-open and I guess this is where your 
sources came from.

Thanks,
   Igor

Roman Kennke wrote:
> Hi,
> 
> I see a small problem in the Swing timer. If you have a look in
> TimerQueue.java, you'll see the following startup code:
> 
>     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;
>         }
>     }
> 
> and the actual thread loop looks like this:
> 
>     public void run() {
>         while (running) {
>             // Do stuff.
>         }
>     }
> 
> You see that the running field is set _after_ the thread has been
> started. It can happen that the started thread kicks off immediately,
> sees that running is (still) false, and stops again, and only then is
> running set to true. I think it's safer to set the running field
> _before_ actually starting the thread:
> 
> 
>     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);
>                     running = true;
>                     timerThread.start();
>                     return null;
>                 }
>             });
>         }
>     }
> 
> What do you think?
> 
> /Roman
> 



More information about the swing-dev mailing list