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