How to use TaskExecutorService discarding overlapping task in java - java

I have a scenario of running 2 separate standalone java polling tool where it would run some specific task with a fixed interval of 5 minutes.
MY scenario is (for each polling service):
1) if a task T0 is required more than 5 minutes to run and meanwhile after 5 minutes T5 comes and tries to execute , i would discard it, not wait,or relaunch (Discard overlapping tasks)
2) The next task would start at T10 normally.
My question is is using Quartz will be an overkill ? I f I use TaskExecutorService how can I check on time X that once task started on time X-5 is already running and I should discard it.
Note:
1) I must use JDK <= 6.0
2) I am not using under any framework like spring.
3) its an desktop tool so I need to launch it and it would run..
Any code snippet or direction is appreciated.
UPDATED for the answer of the comment below:
Yes its between tasks running in a single tool. The tools are different, there is no connection between the tools,they will run separately and has no relation.
a single tool runs a same task in a 5 minutes interval (like every file minute it looks inside a directory for files and if found parses those files and works with them).
If ,say for an example once the task is currently running started from first minute (it may take any amount of time), after 5 minutes the tool launches that task again looking for new files, but this time it will not parse/work with it, as a previous task is already running processing some files.so the new task will not execute and the system will dump it(NO queue/ no waiting / no sequential jobs ).
Another new task will again run on 5x time and if no other is running it will parse and process those files.

After seeing the reply on the question in the comment, you can use Excecutors to obtain a ScheduledExecutorService. Then, you can use the method scheduleWithFixedDelay to submit your task. This method reruns the task with a delay between the runs. The good thing for your case is that the delay counting starts after the current run finishes. This will give you what you want without using a boolean variable or a ReentrantLock as you will not have two tasks running at the same time. You just need to be careful to catch exceptions as an exception will cause subsequent runs of the task to be cancelled.
So lets assume you have a class MyTask which implements runnable
public class MyTask implements Runnable{
public void run() {
try {
//your task code here
} catch (...) {
//deal with the exceptions here
}
}
}
assuming you will run from main method, you can now use the class to schedule the reoccurring task:
public class TaskRunner{
private static final ScheduledExecutorService taskScheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
taskScheduler.scheduleWithFixedDelay(new MyTask(),0,5,TimeUnit.MINUTES);
}
}

The solution is simple: use ScheduledThreadPoolExecutor.scheduleAtFixedRate(task, 5, min). Declare a common boolean variable isRunning=false. Each task checks this variable at the start, and if it is set already, exits, otherwise sets it to true and runs. At the end, sets it to false. Checking and setting should be done in a synchronized block.

Related

cancelling current task and reuse the same thread while creating another task in java

Please take time to read below. Your help will be highly appreciated
I have a scenario where I need to monitor some realtime activity. Say for example a method is getting called in realtime within milli seconds. I have to monitor as if when the method was first called and when the method was called last.
So, after that method is hit last I need to wait for sometime say 10 seconds and see if it doesn't called again within that time. If its not called then I need to run some code.
I want to use ExecuterService and use newCachedThreadPool(). But I am confused on how to implement this.
If you are not sure what I am talking about, take some example of say when there is some network breakdown and u where receiving heartbeats and suddenly u stopped receiving it then you show some error message on screen for e.g. Connection not available. In my case its some third party application which is sending some message and its just one way communication. Like, my application sent some request and other application keep on sending responses. So, I need to monitor that response and somehow need to know when I received the last response.
My approach - I thought of executing a task each time that method is called which will wait for 10 seconds and within 10 seconds, if that method got called again, it will somehow cancel the current task and will create another task (or reuse if possible) which will again run for 10 seconds. This will keep on happening until the last message received (when the method got called last) and after that once 10 sec delay is over, the task will be executed and some code will run to show error message on the UI.
I have used Timer earlier, which solved this problem but created a performance issue as new Timer which a new TimerTask is instantiated every time a new message is received hence creating a hell lot of objects which garbage collector could not reclaim that fast, thus resulting in outOfMemorry Error and making Server non responsive. Obviously it was a bad code that's why I am here for help.
Please help me in giving some approach to solve this problem.
This is quite easy if you approach it with the most basic of tools--sometimes with simple problems the enhanced tools like thread pools just distract from a trivial solution.
Let's say you have a simple thread (Runnable). That thread checks a time stamp to see if that time stamp is 10 seconds old. If it is you notify your listener, if not you delay a few millis and check again.
Now all your method has to do is update the (volatile) time stamp to "now" every time it runs. There may be some other business rules to implement here but it should be a good foundation.
The only issue now is how you notify your listeners. If this happens rarely you can probably call them on the same thread you are checking the time with--but I think you ruled that out. If it happens more often but you don't want/need it to "nest" your notifications, you can have a second thread hanging around with no purpose except to notify the client when triggered by your watcher thread.
If you need to "nest" notifications (notify the listener before the original notification has returned) then you need a thread pool for your notifications to go out on.
Finally I suppose if you want to catch EVERY time your timer isn't called for 10 seconds but you don't want to nest, your timing thread could push "events" onto a threadsafe queue and your "Notification" thread could pull them off and send the events one at a time.
That should cover all the possibilities.
You may use ScheduledExecutorService.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
java.util.concurrent.Executors.newCachedThreadPool :
Creates a thread pool that creates new threads as needed, but will
reuse previously constructed threads when they are available. These
pools will typically improve the performance of programs that execute
many short-lived asynchronous tasks. Calls to execute will reuse
previously constructed threads if available. If no existing thread is
available, a new thread will be created and added to the pool. Threads
that have not been used for sixty seconds are terminated and removed
from the cache. Thus, a pool that remains idle for long enough will
not consume any resources. Note that pools with similar properties but
different details (for example, timeout parameters) may be created
using ThreadPoolExecutor constructors
As you have many short-lived tasks, cached thread pool is best option.
Short example:
public class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s){
this.command=s;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName()+" Start. Command = "+command);
processCommand();
System.out.println(Thread.currentThread().getName()+" End.");
}
private void processCommand() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public String toString(){
return this.command;
}
}
To run WorkerThread use :
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
Runnable worker = new WorkerThread("threadName");
executor.execute(worker);
To stop WorkerThread use:
executor.shutdown();

How to manage single thread execution properly?

I have a process that I want to be triggered by different sources.
Let's say we have one case where we habe some other process (let's call it "manualStarter") under certain conditions wants to trigger this main process. The main process takes a while to complete, let's say 10 seconds to 10 minutes. In case the process is already in progress while the manualStarter is trying to start it, it should not be queued more than once. The second process to trigger the start of the main process could be a "timedStarter" which would trigger the process once in a while, but only if the process is not running, else it would not queue the process to be triggered, instead would try it again some time later.
Now I've tried implementing this kind of process manager by using the isAlive() and join(), but it seems isAlive() is not reliable at all, until it changes its state to alive, 100 threads of this thread might get started (and do sometimes). So seems I couldn't rely on that.
Then I tried using the SingleThreadExecutor service which is closer to what I'm looking for, it's not blocking anything and it only allows a single thread to execute the process, so that's good, however I still don't know how to check the status/lock it properly, or how else I can ensure that the queue for starting the thread doesn't become larger than 1. I read a bit that semaphores are often used for similar kinds of tasks, but I am not sure how I could use them in this scenario.
So how could I achieve what I want? Do I need to implement my own ThreadPoolExecutor? How can I do it? Is there any better way?
Just use a shared flag so the manual starter knows if the thread is running. For example:
// Schedule this to run periodically via ScheduledExecutorService
class ManualStarter {
private final AtomicBoolen isRunning = new AtomicBoolean(false);
private ExecutorService exec = Executors.newSingleThreadedExecutor();
public void run() {
if (!isRunning.getAndSet(true)) {
// It wasn't running so this will start it
exec.submit(new MainProcess(isRunning));
}
}
}
class MainProcess extends Runnable {
private final AtomicBoolean isRunning;
MainProcess(AtomicBoolean isRunning) { this.isRunning = isRunning; }
#Override
public void run() {
// do whatever it does
isRunning.set(false);
}
}
Then somewhere you schedule the main thing to run periodically doing something like:
ScheduledExectorService sched = Executors.newScheduledThreadPool(1);
ManualStarter starter = new ManualStarter();
// Every 10 seconds will check if MainProcess is running and will start
// it if it's not
sched..scheduleAtFixedRate(starter, 0, 10, SECONDS);
You should rather use ExecutorService for that. There is couple of implementations available (including ScheduledExecutorService that allows you to schedule deffered and/or repeating tasks - check Executors). Just pick one that fits your needst the best.
As for conditional execution the task is simple. Define some sort of accessible flag that holds the current "state" of given task. If it is running - do nothing, if it is not running - schedule execution.
Simple example:
//our flag
private volatile AtomicBoolean isRunning=new AtomicBoolean(false);
public void scheduleTask(){
if(isRunning.get()){
return; // do nothing
}else{
synchronized(isRunning){
if(isRunning.get()){
return;
}else{
isRunning.set(true)
scheduleNewTask();
}
}
}
}
For any how-tos check the official Oracle's documentaion about Executors.
I have use AtomicBoolean in this example to mock "mutable" boolean. This can be done with boolean as well but synchronization needs to be done on different object (eg. dedicated private Object lock=new Object();)

Infinite loop + Thread.sleep replace cron job

So I've had an idea in my head today... And I would like to hear some feed-back. I have a Java app which needs to check a directory every 5 minutes. Plain and simple the app needs to run every five minutes.
Seems like a good candidate for cronjob, but I was wondering... why not keep the logic/timing all within the app like so (simplified obviously):
public static void main(String[] args) {
while(true) { // repeatedly execute...
// do the work/job
Thread.sleep(600 * 1000); // make the thread sleep for 5 minutes
}
}
One significant downside I see is "How do we stop this app once it starts? Deleting it?
Are there any other significant draw-backs to this besides that one?
Should I stop daydreaming and just use cron jobs?
A number of significant drawbacks:
If you ever want to change the polling frequency (i.e. do it every 2 minutes, or every 10 minutes), you have to change the program. This is especially difficult if you have an irregular polling schedule, something like once every 5 minutes on Monday through Friday, but once every 15 minutes on Saturday and Sunday. Sure, you don't think your program will ever need to do that, but requirements evolve.
As you say, killing the process is the only way to stop the program. And killing it in mid-process might be a bad thing. You could of course add some cancel logic, but that's additional development time.
The program is occupying memory while it's sitting there doing nothing (most of the time). This is a waste of resources. Probably not a huge deal when you're working with a system that has many gigabytes of memory, but it becomes an issue when you're working on embedded systems with limited memory.
You're wasting your time writing your own scheduling, which you then have to debug and maintain, when there's already a perfectly good scheduler built into the operating system.
I call this program a "catnap program" because it acts just like a cat: it sleeps most of the time, waking up now and then to stretch and maybe bat a string around for a few minutes, and then goes back to sleep. Programs are not cats.
You can run a task at fixed rate using ScheduledExecutorService and stop it on some action (here by reading System.in):
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// do some work
}
}, 0, 5, TimeUnit.MINUTES); // every 5 minutes
// when anything is entered, the task is stopped
Scanner sc = new Scanner(System.in);
String whatever = sc.next();
// shutdown the executor
ses.shutdown();
ses.awaitTermination(15, TimeUnit.SECONDS);
}
A solution like the one suggested has the advantage that it will work on an operating system that does not have cron (but every OS will have some kind of scheduler).
On the other hand using cron has these advantages:
The task will be run at the next scheduled time even if it crashes; the solution shown won't run again after a crash until someone restarts it.
Cron will start running the task again after a reboot; the solution proposed doesn't do that.
When the task stops and then shuts down periodically, memory leaks are less critical than in a long-running process.
This list could doubtless be made longer by enumerating more features that have been added to OS level job schedulers over time.
I would use a quartz scheduler within my application. link http://quartz-scheduler.org/
it does control, when you start your application it runs, and when your application stops it will stop. Granted there is more setup, but it's pretty flexiable.

Re-executing a Java program after a certain delay

I want to execute a Java program in Eclipse multiple times with a certain delay.
I was trying to use ScheduleAtFixedRate() to re-execute the program after a certain interval of time. So what is the main difference between ScheduleAtFixedRate() and ScheduledExecutorService?
What is the advantage of using the latter?
Does it continue running the schedule of execution when the computer is set on a sleep mode?
Provided you mean .scheduleAtFixedRate() (note the little s), then it is a method provided by ScheduledExecutorService. As such, there is no {dis,}advantage to using either.
You can create a ScheduledExecutorService by calling, for instance:
final ScheduledExecutorService service
= Executors.newScheduledThreadPool(...);
service.scheduleAtFixedRate(...);
As to:
Does it continue running the schedule of execution when the computer is set on a sleep mode?
No. It is the OS which puts the computer to sleep, and it is the OS which you should instruct to wake up at the time(s) you want. A running Java program is a JVM is a process is ultimately controlled by the OS.
ScheduledExecutorService is an interface that defines the behaviour of a task executor and ScheduleAtFixedRate() is method of this interface which expects the implementation class i.e the executor to execute the input task at fixed interval.
When your computer goes to sleep or hibernates nothing will execute.

Schedule a single-threaded repeating runnable in java, but skip the current run if previous run is not finished

Sometimes the duration of a repeated task is longer than its period (In my case, this can happen for hours at a time). Think of a repeated task that takes 7 minutes to run and is scheduled to run every 10 minutes, but sometimes takes 15 minutes for each run for a few hours in a row.
The Timer and ScheduledThreadPoolExecutor classes both have a scheduleAtFixedRate method that is usually used for this type of functionality. However, both have the characteristic that they 'try to catch up when they fall behind'. In other words, if a Timer falls behind by a few executions, it builds up a queue of work that will be worked on continuously until it catches back up to the number of runs that would have happened if none of the tasks had taken longer than the specified period. I want to avoid this behavior by skipping the current execution if the previous run is not complete.
I have one solution that involves messing around with the afterExecution method of a pooled executor, recalculating a delay, and rescheduling the runnable with the new delay, but was wondering if there's a simpler way, or if this functionality already exists in a common library somewhere. I know about scheduling with a fixed delay rather than a fixed period, but this will not work for me since it's important to try to execute the tasks at their fixed times. Are there any simpler options than my afterExecution solution?
I think what you want is for the long-running task itself to not run in the ScheduledExecutorService itself, but in a background thread. Then the fixed-rate task will always complete quickly, since it is only used for checking whether to start the actual task in the background (or not, if it's still running from last time).
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
final Runnable actualTask = null;
executorService.scheduleAtFixedRate(new Runnable() {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private Future<?> lastExecution;
#Override
public void run() {
if (lastExecution != null && !lastExecution.isDone()) {
return;
}
lastExecution = executor.submit(actualTask);
}
}, 10, 10, TimeUnit.MINUTES);
You could use scheduleWithFixedDelay method instead. It's similar but this one does not have a queue for missed runs and instead starts counting again only when the current Runnable was terminated.
The documentation states the reexecution of the Runnable will be scheduled based on the delay parameter:
The delay between the termination of one execution and the commencement of the next.
Make a third class, say called Coordinator. Coordinator has a synchronized startRunning() method which sets isRunning to true and returns true if another thread was not running already. There should also be a synchronized stopRunning method which sets isRunning to false. It returns true if a runnable is already running. You make a single instance of this class and pass a reference to all of the runnables you construct. In the runnable's run method you first call startRunning and check the return to verify that another one isn't running already. Make sure to put the code in run() in a try-finally and call stopRunning from within the finally block.

Categories