Thread.sleep and System time change

H

huy

Hi All,

Wondering if anyone could help with this problem.

I have a label which gets updated with the time every one second using
the following code.

clockThread = new Thread()
{
public void run()
{
for (; ; ) {
jobList.clock.setText(timeFormat.format(new Date()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Logger.error("Clock interrupted");
}
}
}
};

I have another bit of code which updates the System time and calls
clockThread.interrupt(). I do this because I read somewhere that
Thread.sleep() operates via a fixed timestamp i.e it's 9.00.00 and
sleep(1000) will wakeup at 9.00.10, not 1 sec from now (i.e relative to
current time/moment).

The problem I am having is that if I set the time to a time past the
current time eg. 9.15.00, then the above code works and my label gets
updated. However, if I set the time to somewhere before the current time
eg. 8.30.00, then the above code does not update my label, although the
thread does get interrupted ??? Huhhh ???

My guess: something is going on in one of the AWT threads which stops
the label from being updated to the current value, but I don't know what ?

Any help is greatly appreciated.

Regards,

Huy
 
M

Matt Humphrey

huy said:
Hi All,

Wondering if anyone could help with this problem.

I have a label which gets updated with the time every one second using
the following code.

clockThread = new Thread()
{
public void run()
{
for (; ; ) {
jobList.clock.setText(timeFormat.format(new Date()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Logger.error("Clock interrupted");
}
}
}
};

I have another bit of code which updates the System time and calls
clockThread.interrupt(). I do this because I read somewhere that
Thread.sleep() operates via a fixed timestamp i.e it's 9.00.00 and
sleep(1000) will wakeup at 9.00.10, not 1 sec from now (i.e relative to
current time/moment).

The problem I am having is that if I set the time to a time past the
current time eg. 9.15.00, then the above code works and my label gets
updated. However, if I set the time to somewhere before the current time
eg. 8.30.00, then the above code does not update my label, although the
thread does get interrupted ??? Huhhh ???

I think you answered your own question. Presuming that sleep assigns the
time when the thread should wake up, by setting the clock back in time it
will not wake up for a long time. That is, if the time is now 9:00:00,
sleeping 1000 means it will wake up at 9.00.01. When you set the clock
back, the time is now 8:30, so the sleep will not wake up for another half
hour.

Check out this:
http://mindprod.com/jgloss/sleep.html

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
H

huy

Matt said:
I think you answered your own question. Presuming that sleep assigns the
time when the thread should wake up, by setting the clock back in time it
will not wake up for a long time. That is, if the time is now 9:00:00,
sleeping 1000 means it will wake up at 9.00.01. When you set the clock
back, the time is now 8:30, so the sleep will not wake up for another half
hour.

Check out this:
http://mindprod.com/jgloss/sleep.html

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
Hi Matt,

I know what you mean (because I read the same site), but it doesn't
really answer why although the sleep gets interrupted on both counts of
setting the system time (before and after current time), my label is not
getting updated when I set the time to sometime before the current time.
Do I have to call something explicitly to get the label to update
besides label.setText() ?

Thanks,

Huy
 
T

Tony Morris

I have a label which gets updated with the time every one second using
No you don't have what you think you do.
A common misconception is that Thread.sleep(long x) causes the current
thread of execution to stop running for the specified period of time (in
milliseconds) before resuming execution. This is incorrect.

Without repeating what I've already attempted to document in less formal
terms, I refer you to:
http://www.xdweb.net/~dibblego/java/faq/answers.html#q33

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
H

huy

Tony said:
No you don't have what you think you do.
A common misconception is that Thread.sleep(long x) causes the current
thread of execution to stop running for the specified period of time (in
milliseconds) before resuming execution. This is incorrect.

Without repeating what I've already attempted to document in less formal
terms, I refer you to:
http://www.xdweb.net/~dibblego/java/faq/answers.html#q33

That's fair enough. However, it's not so much the accuracy of the sleep
that I'm concerned about, but the fact that once "it enters the
execution state"; which I assume is the state it's in once the
InterruptedException is thrown, it doesn't update my label.

Regards,

Huy
 
M

Matt Humphrey

huy said:
That's fair enough. However, it's not so much the accuracy of the sleep
that I'm concerned about, but the fact that once "it enters the
execution state"; which I assume is the state it's in once the
InterruptedException is thrown, it doesn't update my label.

Ok, I think I'm following your problem more closely now. After you change
the system time, the interrupt is meant to restart the clock using the new
time and update the display, thereby avoiding the clock-setback problem. So
currently the time updates about once a second and then you change the time
and the label stops changing. One thing to think about is that if your time
format is is hh:mm:ss the actual seconds will not have changed
noticebly--it's still within the current second.

So really, if you put in print statements that print the current time before
and after the sleep and in the exception, you find that the sleep is
sleeping much too long. (and try interrupting more than once.) At first I
thought that it wouldn't matter if the Date system and Thread system used
different clocks because regardless of whatever time is NOW, the thread
would wake up at NOW + X. However, that's not necessarily true. The thread
may be set to wake up at NOW+X, but the scheduler cannot go backwards in
time. NOW+X has already passed and will not occur again. I can only refer
back to Roedy's page where he says that if someone fiddles with the system
clock, sleep may take a long time or no time. I would have thought that
that warning applied only to sleeps that were already in progress, but maybe
there is some overlap between setting the clock and interrupting the thread
whereby the time is not changed within the scheduler by the time the
interrupt goes off and the re-sleep is using the old time when the new time
comes in.

I don't think I can tell you any more until I've replicated your problem
here.

Good luck,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
H

huy

huy said:
Hi All,

Wondering if anyone could help with this problem.

I have a label which gets updated with the time every one second using
the following code.

clockThread = new Thread()
{
public void run()
{
for (; ; ) {
jobList.clock.setText(timeFormat.format(new Date()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Logger.error("Clock interrupted");
}
}
}
};

I added a repaint() method after the setText method, and all is
working. The repaint() seems to wake up the AWT event thread and updates
the gui.

Thanks for all the responses.

Huy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top