Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScheduledExecutorService wait for task to complete

I am creating a new thread to check a folder for new files then sleeping for a defined period of time.

My preference would be to use the ScheduledExecutorService, however, I can't find any documentation to clarify if this waits for the currently running task to complete before starting a new one.

For example, in the following code;

Integer samplingInterval = 30;
ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10);
executorService.scheduleAtFixedRate(new WatchAgent(agentInfo), 
                                    0, 
                                    samplingInterval, 
                                    TimeUnit.SECONDS);

If the run() of WatchAgent takes longer than 30 seconds, will a new agent be created before it finishes?

Secondly, if I create an instance of WatchAgent, can I keep using the same instance for each periodic run?

like image 394
owenrumney Avatar asked Nov 25 '13 16:11

owenrumney


People also ask

Is ScheduledExecutorService asynchronous?

ScheduledExecutorService is an ExecutorService which can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService .

Can we cancel callable task?

You can cancel a future using Future. cancel() method. It attempts to cancel the execution of the task and returns true if it is cancelled successfully, otherwise, it returns false. The cancel() method accepts a boolean argument - mayInterruptIfRunning .


2 Answers

Per the javadoc of scheduleAtFixedRate:

If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.

scheduleAtFixedRate by definition takes a single Runnable instance. There is no way for you to provide different instances for each invocation of run. So to answer your question, the same instance will always be used for each periodic run.

like image 57
John B Avatar answered Sep 21 '22 12:09

John B


Try this test code below.

1) Yes, it seems to wait until run() is finished.

2) Yes, seems it is using the same instance's run method (the one you passed in when you called scheduleAtFixedRate; this makes perfect sense btw).

import java.util.Date;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class Test006 {

    public static void main(String[] args) {
        Object agentInfo = null;
        Integer samplingInterval = 30;
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(10);
        executorService.scheduleAtFixedRate(new WatchAgent(agentInfo), 0, samplingInterval, TimeUnit.SECONDS);
    }

}


class WatchAgent implements Runnable {

    public WatchAgent(Object info){

    }

    public void run(){
        try{
            System.out.println("Running " + this.hashCode() + " - started on/at " + (new Date()));
            Thread.sleep(60000);
            System.out.println("Running " + this.hashCode() + " - finished on/at " + (new Date()));
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
}

Output:

Running 1322575120 - started on/at Mon Jul 08 19:58:41 IST 2019
Running 1322575120 - finished on/at Mon Jul 08 19:59:41 IST 2019
Running 1322575120 - started on/at Mon Jul 08 19:59:41 IST 2019
Running 1322575120 - finished on/at Mon Jul 08 20:00:41 IST 2019
Running 1322575120 - started on/at Mon Jul 08 20:00:41 IST 2019
...
like image 30
peter.petrov Avatar answered Sep 21 '22 12:09

peter.petrov