I want to implement a very simple client to server heartbeat in java. The most simple approach seems to be through sleep. Consider the metacode below.
class MyClass
Thread heartbeatThread = new Thread();
public void() startHeartBeat{
Thread.sleep(4000);
sock.write("H");
}
Is this an adequate solution, or are there pitfalls I'm not considering?
I've also considered using the java.util.Timer.scheduleAtFixedRate
approach. Would this be more robust/reliable? If so, why? Here's an example (it's not as clean IMO):
class HeartBeat
{
Timer timer=new Timer();
public void scheduleHeartBeat(int delay, int period) {
timer.scheduleAtFixedRate( new HeartBeatTask(), delay, period);
}
}
class HeartBeatTaskextends TimerTask {
public void run() {
sock.write("H");
}
Will the second approach be granted higher priority?
Firstly, your Thread
-based idiom will not schedule at fixed rate without an infinite loop.
That's one disadvantage too: you probably want to set some condition to exit the loop.
You also need to catch InterruptedException
when invoking static Thread.sleep
.
Another popular idiom for scheduled execution is by using a ScheduledExecutorService
.
Find the 3 alternatives below:
Timer
// says "foo" every half second
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("foo");
}
}, 0, 500);
In fixed-rate execution, each execution is scheduled relative to the scheduled execution time of the initial execution. If an execution is delayed for any reason (such as garbage collection or other background activity), two or more executions will occur in rapid succession to "catch up."
Docs here.
Infinite loop
new Thread() {
@Override
public void run() {
while (true) {
// Says "blah" every half second
System.out.println("blah");
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
// nope
}
}
}
}.start();
Thread.sleep
is still subject to the precision and accuracy of system timers and schedulers. ... and requires catching
InterruptedException
.
Docs here.
Also:
try
/ catch
.Executors
ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor();
es.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
// Says "bar" every half second
System.out.println("bar");
}
},
0, 500, TimeUnit.MILLISECONDS);
Callable
s (not at fixed rate though) and re-use the ExecutorService
. The documentation for java.util.Timer
actually mentions ScheduledThreadPoolExecutor
(implementing the ScheduledExecutorService
interface) as a "more versatile replacement for the Timer
/TimerTask
combination".If any execution of this task takes longer than its period, then subsequent executions may start late,
Docs here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With