Here's my simple code to loop every second (doesn't need to be exact) and kick off a job if necessary:
while (true) {
// check db for new jobs and
// kick off thread if necessary
try {
Thread.sleep(1000);
} catch(Throwable t) {
LOG.error("", t);
}
}
This code has worked fine for several months. Just yesterday we started having problems where one of our servers seems to be hung in the Thread.sleep(1000) method. IOW - it's been over a day and the Thread.sleep hasn't returned. I started up jconsole and get this info about the thread.
Name: Thread-3
State: TIMED_WAITING
Total blocked: 2 Total waited: 2,820
Stack trace:
java.lang.Thread.sleep(Native Method)
xc.mst.scheduling.Scheduler.run(Scheduler.java:400)
java.lang.Thread.run(Thread.java:662)
Scheduler.java:400 is the Thread.sleep line above. The jconsole output doesn't increment "Total waited" every second as I'd expect. In fact it doesn't change at all. I even shut down jconsole and started it back up in the hopes that maybe that would force a refresh, but only got the same numbers again. I don't know what other explanation there could be besides that the jvm has incorrectly hung on the sleep command. In my years, though, I've had so few problems with the jvm that I assume it must be an oversight on my part.
note: The other thing to note is that no other thread is active. IOW - the cpu is nearly idle. I read somewhere that Thread.sleep could be legitimately starved if another thread was active, but that isn't the case here.
solaris version:
$ uname -a
SunOS xcmst 5.10 Generic_141415-08 i86pc i386 i86pc
java version:
$ java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)
In addition to what bdonlan mentioned you may want to look into ScheduledThreadPoolExecutor. I work on a very similar type of project and this object has made my life easier, thanks to this little snippet.
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
I hope this helps!