Reputation: 95
I have researched for this subject a lot but couldn't find any useful information. And I have decided to ask my first question on this platform. So, I am using a scheduled executor to repeat task in a specific period. Everything is fine. But there is a misunderstanding.... My code executes task but if task takes longer than schedule time then it waits to finish task and later starts execute new task. I want it to do that execute task when schedule time arrives and don't wait previous task to finish. How can I achieve this? I used SwingWorker on a swing project but this project is not a swing project. Thanks for reading.
Main method
LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - Available processors for Thread Pool: " + AVAILABLE_PROCESSORS);
ScheduledExecutorService executor = Executors.newScheduledThreadPool(AVAILABLE_PROCESSORS);
LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [ScheduledExecutorService] instance created.");
MainWorker task = new MainWorker();
LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Main worker] created...");
executor.scheduleWithFixedDelay(task, 0, Config.CHECK_INTERVAL, TimeUnit.SECONDS);
Main Worker
public class MainWorker implements Runnable {
private final NIFIncomingController controller = new NIFIncomingController();
@Override
public void run() {
LogFactory.log(LogFactory.INFO_LEVEL, Config.MODULE_NAME + " - [Task] executed - [" + Thread.currentThread().getName() + "]");
controller.run();
}
}
Upvotes: 1
Views: 1519
Reputation: 1
This can be achieved by using a single executor service. Say your schedule time is Y
executorService.schedule(taskObject1, 0/*Initial Delay*/, 2Y); executorService.schedule(taskObject2, Y/*Initial Delay*/, 2Y);
Upvotes: 0
Reputation: 5142
You can try to combine several executors in order to achieve the desired behavior. Please, find an example code below:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class CombinedThreadPoolsExample {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static final int INITIAL_DELAY = 0;
private static final int FIXED_DELAY_IN_MILLISECONDS = 1000;
private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 2;
public static void main(String[] args) {
int availableProcessors = Runtime.getRuntime().availableProcessors();
System.out.println("Available processors: [" + availableProcessors + "].");
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(availableProcessors);
Runnable runnableThatTakesMoreTimeThanSpecifiedDelay = new Runnable() {
@Override
public void run() {
System.out.println("Thread name: [" + Thread.currentThread().getName() + "], time: [" + DATE_FORMAT.format(new Date()) + "].");
try {
Thread.sleep(TASK_EXECUTION_IN_MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
singleThreadScheduledExecutor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
fixedThreadPool.execute(runnableThatTakesMoreTimeThanSpecifiedDelay);
}
}, INITIAL_DELAY, FIXED_DELAY_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
}
}
The first lines of the output are the following for my machine:
Available processors: [8].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:00.103].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:01.104].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:02.105].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:03.105].
Thread name: [pool-1-thread-5], time: [2017-12-25 11:22:04.106].
Thread name: [pool-1-thread-6], time: [2017-12-25 11:22:05.107].
Thread name: [pool-1-thread-7], time: [2017-12-25 11:22:06.107].
Thread name: [pool-1-thread-8], time: [2017-12-25 11:22:07.107].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:22:08.108].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:22:09.108].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:22:10.108].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:22:11.109].
However, beware of relying on such solution when a task execution can take a long time, compare to a pool size. Let's say we increase the time necessary for a task execution:
private static final int TASK_EXECUTION_IN_MILLISECONDS = FIXED_DELAY_IN_MILLISECONDS * 10;
This won't cause any exceptions during execution, but cannot enforce the specified delay between executions. It can be observed in the execution output after the aforementioned delay alteration:
Available processors: [8].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:23.258].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:24.260].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:25.261].
Thread name: [pool-1-thread-4], time: [2017-12-25 11:31:26.262].
Thread name: [pool-1-thread-5], time: [2017-12-25 11:31:27.262].
Thread name: [pool-1-thread-6], time: [2017-12-25 11:31:28.263].
Thread name: [pool-1-thread-7], time: [2017-12-25 11:31:29.264].
Thread name: [pool-1-thread-8], time: [2017-12-25 11:31:30.264].
Thread name: [pool-1-thread-1], time: [2017-12-25 11:31:33.260].
Thread name: [pool-1-thread-2], time: [2017-12-25 11:31:34.261].
Thread name: [pool-1-thread-3], time: [2017-12-25 11:31:35.262].
Upvotes: 1