Heartbeat in Java: timerTask or thread.sleep()? - java

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);
Pros: simple
Cons:
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();
Pros: super simple. You can vary your recurring delay programmatically.
Cons: Thread.sleep is still
subject to the precision and accuracy of system timers and schedulers.
... and requires catching InterruptedException.
Docs here.
Also:
your infinite loop might require a (somehow potentially cumbersome) breaking condition
no initial delay setting unless applied manually before infinite loop, which would require another 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);
Pros: this is the most recent feature of the 3. Very simple and elegant - you can also schedule Callables (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".
Cons as documented:
If any execution of this task takes longer than its period, then subsequent executions may start late,
Docs here.

Yes, I don't know how timers are implemented internally, but what I do understand here is, if you use sleep, you will have to handle InterruptedException, and eating up that exception may not be a good practice. moreover timer tasks would be running within its thread space, and you have better control over it.
You can stop the timer any time if you want, In this case, you may not be able to do that

If you use the sleep approach, there are some issues to consider.
One is that the sleep time isn't exact, and you could have drift over time (maybe while your thread is sleeping another application hogs CPU and it takes longer than expected for your thread to send its heartbeat, now the next time the thread sends a heartbeat is delayed), your sleep time will be augmented by various things incrementally (you won't sleep for less than your sleep time but may frequently sleep for a bit more), and those increments will add up over time.
Another is that you could have a problem with the socket, you would have to write code to handle making a new connection.
The thread would need to be well-behaved and respond to interruption, or else be a daemon thread. If it had to share data across threads you'd need to be aware of memory visibility issues.
Using a timer would mean each launching of a task would have a fresh start and you wouldn't be vulnerable to accumulated delays or stale network connections.

Related

How not to start ScheduledExecutorService task if previous one is not finished

My problem is we have to give it a fixed schedule time to make it start task. Lets say i give 10 seconds and my task has average finish time of 10-15 seconds. Thus after some time waiting threads in quque causes huge memory consumption. If i use syncronized for the method above problem will occur. If i don't use syncronized then i am wasting resources ( cpu) because i dont need to run task if not finished. So i thought a solution of recursive call of task but i believe recursive threads will add more memory problems... what should i do? Shortly i just want to be able to call a task when it is finished. Not fixed time.
public void myScheduledTask{
doJob(); ( use countdown latch to control waiting if necessary)
TimeUnit.SECONDS.sleep(x);
new Thread( new Runnable( { mySchedulTask(); } ));
or
executor.execute( a thread that call myScheduledTask() method);
}
The option that sounds like what you're trying to accomplish:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(count);
ScheduledFuture<?> future = executor.scheduleWithFixedDelay(
task,
delay,
delay,
TimeUnit.MILLISECONDS
);
This would start your task and execute it after delay milliseconds after the previous completion. Count should be the number of threads you want to use, 1 is acceptable. This also lets you stop the task using the future.
The problems with your example. a) You are sleeping on an executor thread. Dont do this let the executor handle it. If you were using a threadpool of 1 then this executor couldn't do any work while you're waiting. b) Starting a new thread is taking control from the executor... just use the executor, then you have some control over the execution.
If you really wanted to stick with the form you have.
class RecurringTask implements Runnable{
#Override
public void run(){
doJob();
executor.schedule(this, delay, TimeUnit.MILLISECONDS);
}
}
Now you will be creating Futures that you never use, so it will be harder to control the execution of the task.
Create static member in your task class - Lock.
In doJob avoid performing job if lock is already aquired :
if (lock.tryLock()) {
try {
// do the job
} finally {
lock.unlock();
}
} else {
// log the fact you skipped the job
return;
}

Java Executor with throttling/throughput control

I'm looking for a Java Executor that allows me to specify throttling/throughput/pacing limitations, for example, no more than say 100 tasks can be processed in a second -- if more tasks get submitted they should get queued and executed later. The main purpose of this is to avoid running into limits when hitting foreign APIs or servers.
I'm wondering whether either base Java (which I doubt, because I checked) or somewhere else reliable (e.g. Apache Commons) provides this, or if I have to write my own. Preferably something lightweight. I don't mind writing it myself, but if there's a "standard" version out there somewhere I'd at least like to look at it first.
Take a look at guavas RateLimiter:
A rate limiter. Conceptually, a rate limiter distributes permits at a
configurable rate. Each acquire() blocks if necessary until a permit
is available, and then takes it. Once acquired, permits need not be
released. Rate limiters are often used to restrict the rate at which
some physical or logical resource is accessed. This is in contrast to
Semaphore which restricts the number of concurrent accesses instead of
the rate (note though that concurrency and rate are closely related,
e.g. see Little's Law).
Its threadsafe, but still #Beta. Might be worth a try anyway.
You would have to wrap each call to the Executor with respect to the rate limiter. For a more clean solution you could create some kind of wrapper for the ExecutorService.
From the javadoc:
final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second"
void submitTasks(List<Runnable> tasks, Executor executor) {
for (Runnable task : tasks) {
rateLimiter.acquire(); // may wait
executor.execute(task);
}
}
The Java Executor doesn't offer such a limitation, only limitation by amount of threads, which is not what you are looking for.
In general the Executor is the wrong place to limit such actions anyway, it should be at the moment where the Thread tries to call the outside server. You can do this for example by having a limiting Semaphore that threads wait on before they submit their requests.
Calling Thread:
public void run() {
// ...
requestLimiter.acquire();
connection.send();
// ...
}
While at the same time you schedule a (single) secondary thread to periodically (like every 60 seconds) releases acquired resources:
public void run() {
// ...
requestLimiter.drainPermits(); // make sure not more than max are released by draining the Semaphore empty
requestLimiter.release(MAX_NUM_REQUESTS);
// ...
}
no more than say 100 tasks can be processed in a second -- if more
tasks get submitted they should get queued and executed later
You need to look into Executors.newFixedThreadPool(int limit). This will allow you to limit the number of threads that can be executed simultaneously. If you submit more than one thread, they will be queued and executed later.
ExecutorService threadPool = Executors.newFixedThreadPool(100);
Future<?> result1 = threadPool.submit(runnable1);
Future<?> result2 = threadPool.submit(runnable2);
Futurte<SomeClass> result3 = threadPool.submit(callable1);
...
Snippet above shows how you would work with an ExecutorService that allows no more than 100 threads to be executed simultaneously.
Update:
After going over the comments, here is what I have come up with (kinda stupid). How about manually keeping a track of threads that are to be executed ? How about storing them first in an ArrayList and then submitting them to the Executor based on how many threads have already been executed in the last one second.
So, lets say 200 tasks have been submitted into our maintained ArrayList, We can iterate and add 100 to the Executor. When a second passes, we can add few more threads based on how many have completed in theExecutor and so on
Depending on the scenario, and as suggested in one of the previous responses, the basic functionalities of a ThreadPoolExecutor may do the trick.
But if the threadpool is shared by multiple clients and you want to throttle, to restrict the usage of each one of them, making sure that one client won't use all the threads, then a BoundedExecutor will do the work.
More details can be found in the following example:
http://jcip.net/listings/BoundedExecutor.java
Personally I found this scenario quite interesting. In my case, I wanted to stress that the interesting phase to throttle is the consuming side one, as in classical Producer/Consumer concurrent theory. That's the opposite of some of the suggested answers before. This is, we don't want to block the submitting thread, but block the consuming threads based in a rate (tasks/second) policy. So, even if there are tasks ready in the queue, executing/consuming Threads may block waiting to meet the throtle policy.
That said, I think a good candidate would be the Executors.newScheduledThreadPool(int corePoolSize). This way you would need a simple queue in front of the executor (a simple LinkedBlockingQueue would suit), and then schedule a periodic task to pick actual tasks from the queue (ScheduledExecutorService.scheduleAtFixedRate). So, is not an straightforward solution, but it should perform goog enough if you try to throttle the consumers as discussed before.
Can limit it inside Runnable:
public static Runnable throttle (Runnable realRunner, long delay) {
Runnable throttleRunner = new Runnable() {
// whether is waiting to run
private boolean _isWaiting = false;
// target time to run realRunner
private long _timeToRun;
// specified delay time to wait
private long _delay = delay;
// Runnable that has the real task to run
private Runnable _realRunner = realRunner;
#Override
public void run() {
// current time
long now;
synchronized (this) {
// another thread is waiting, skip
if (_isWaiting) return;
now = System.currentTimeMillis();
// update time to run
// do not update it each time since
// you do not want to postpone it unlimited
_timeToRun = now+_delay;
// set waiting status
_isWaiting = true;
}
try {
Thread.sleep(_timeToRun-now);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// clear waiting status before run
_isWaiting = false;
// do the real task
_realRunner.run();
}
}};
return throttleRunner;
}
Take from JAVA Thread Debounce and Throttle

TimerTask vs Thread.sleep vs Handler postDelayed - most accurate to call function every N milliseconds?

What is the most accurate way to call a function every N milliseconds?
Thread with Thread.sleep
TimerTask
Handler with postDelayed
I modified this example using Thread.sleep and it's not very accurate.
I'm developing a music app that will play sounds at a given BPM. I understand it's impossible to create an entirely accurate metronome and I don't need to - just looking to find the best way to do this.
Thanks
There are some disadvantages of using Timer
It creates only single thread to execute the tasks and if a task
takes too long to run, other tasks suffer.
It does not handle
exceptions thrown by tasks and thread just terminates, which affects
other scheduled tasks and they are never run
ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case.. scheduleAtFixedRate(...) and scheduleWithFixedDelay(..)
class MyTask implements Runnable {
#Override
public void run() {
System.out.println("Hello world");
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);
On Android you can create Thread with it's own Handler/Message Queue. It's quite accurate. When you see Handler documentation you can see, that it was designed for that.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
They are all the same precision-wise. Java timing precision is subject to the precision and accuracy of system timers and schedulers and is not guaranteed. See Thread.sleep and Object.wait API.
Using TimerTask for the loop action is the better one. Recommend

Java: Thread/task expiration after specified milliseconds

In Java is there a sane way to have a thread/task run continuously and then end after a specified run time (preferably without using several timers)?
For instance, if I have a TimerTask, there doesn't seem to be a way to schedule that task to end after a certain number of milliseconds or at a specific time with the Timer class.
Sure, I can schedule a task to repeat after a number of milliseconds, but what if I want it to end after one iteration? I have to run another timer within this scheduled task? I'm hoping for a more elegant answer than that.
The answer provided in this question could work, but it is definitely not what I had in mind.
Essentially, I'm looking for something similar to the AutoReset property on C#'s System.Timers.Timer class
You can use an ExecutorService, grab the Future you get and .cancel() it after the time you want:
final Future<Whatever> f = executor.submit(...);
TimeUnit.SECONDS.sleep(xxx);
f.cancel(true);
Or you can have two services: one which executes, another which uses a ScheduledExecutorService for the cancellation.
NOTE: TimerTask depends on the system time, use a ScheduledExecutorService instead.
Simply create another thread and have it time it for when it wants the other thread to stop:
class ThreadTimer implements Runnable {
public void run()
{
Thread.sleep(3000);
MainThread.stopThread();
}
}
class MainThread implements Runnable {
public boolean running = true;
public void run()
{
// thread running code
if(!running)
return;
}
public static void stopThread()
{
running = false;
}
}
Where 3000 is the amount of time in milliseconds from when you want the thread to stop.
Since Thread.stop() is deprecated in Java, the next best way is to only execute the thread if a boolean is set to true. When you call to stop the thread, you're setting that boolean to false, making the code in the thread not run.
Because the void run() doesn't repeat itself and only executes once, if you set the boolean to false, it simply returns run() and halts the thread's execution.
If your task is running in a loop, you can check the current time on each iteration, and terminate the loop if enough time has passed.
Or, if your task involves sleeps, you can set a timer on another thread to call Thread.interrupt on the task.
The only other option would be to set a timer on another thread to call Thread.stop. However, Thread.stop has been deprecated, and there's no safe way to stop a general thread in Java.

ScheduledExecutorService multiple threads in parallel

I'm interested in using ScheduledExecutorService to spawn multiple threads for tasks if task before did not yet finish. For example I need to process a file every 0.5s. First task starts processing file, after 0.5s if first thread is not finished second thread is spawned and starts processing second file and so on. This can be done with something like this:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4)
while (!executor.isShutdown()) {
executor.execute(task);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// handle
}
}
Now my question: Why I can't do it with executor.scheduleAtFixedRate?
What I get is if the first task takes longer, the second task is started as soon as first finished, but no new thread is started even if executor has pool of threads. executor.scheduleWithFixedDelay is clear - it executes tasks with same time span between them and it doesn't matter how long it takes to complete the task. So probably I misunderstood ScheduledExecutorService purpose.
Maybe I should look at another kind of executor? Or just use code which I posted here? Any thoughts?
I've solved the problem by launching a nested anonymous runnable in each scheduled execution:
final ScheduledExecutorService service = Executors.newScheduledThreadPool(POOL_SIZE);
final Runnable command = new SlowRunnable();
service.scheduleAtFixedRate(
new Runnable() {
#Override
public void run() {
service.execute(command);
}
}, 0, 1, TimeUnit.SECONDS);
With this example there will be 1 thread executing at every interval a fast instruction, so it will be surely be finished when the next interval is expired. The remaining POOL_SIZE-1 threads will be executing the SlowRunnable's run() in parallel, which may take longer time than the duration of the single interval.
Please note that while I like this solution as it minimize the code and reuse the same ScheduledExecutorService, it must be sized correctly and may not be usable in every context: if the SlowRunnable is so slow that up to POOL_SIZE jobs get executed together, there will be no threads to run the the scheduled task in time.
Also, if you set the interval at 1 TimeUnit.NANOSECONDS it will probably became too slow also the execution of the main runnable.
One of the scheduleAtFixedRate methods is what you're looking for. It starts a task in a thread from the pool at the given interval, even if previous tasks haven't finished. If you're running out of threads to do the processing, adjust the pool size constraints as detailed in the ThreadPoolExecutor docs.

Categories

Resources