Shutdown ExecutorService when at least one Future fails - java

I would like to implement shutting down ExecutorService when at least one Future fails. If this is not possible to be done with ExecutorService please tell me if there is some class that supports this (or maybe I should implement this on my own?). Code:
ExecutorService executorService = Executors.newSingleThreadExecutor();
public void runCommand(String command) {
/* This is done in reaction for an event, so we do not know when the new Runnable will be
submitted... sometimes we can have 10 tasks on the ExecutorService 'queue', sometimes 100 etc. */
Runnable runnable = () -> {
logger.info("do something");
};
Future<?> runnableFuture = executorService.submit(runnable );
// Somehow 'attach' to ExecutorService and when at least Future<?> from its internal queue is finished and fails -> then shutdown the whole ExecutorService.
}

Related

How to timeout a newSingleThreadScheduledExecutor

In Android, I'm trying to start a thread that kills itself or is canceled by the executor after some timeout limit for example 20 seconds? So the runnable would only do its work for that many seconds than cancel...
How do I achieve this? I'm currently starting it as the following.
Executors.newSingleThreadScheduledExecutor().schedule(myRunnable, 0, TimeUnit.MILLISECONDS);
My runnable looks like this
static class MyRunnable implements Runnable {
MyRunnable(Helper _helper) {
helper = _helper;
}
public void run() {
}
}
If you want to stop a task that has already been submitted to an ExecutorService then you'll need to deal with Future objects.
Like this answer:
Stop a Runnable submitted to ExecutorService
Basically you will submit a Runnable and get back a Future object that you can use to cancel it.
Specific to your concern: Stop one task in 20 seconds you could use handoff the Future object from the first task to another like so:
ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// Schedule your audio processing job like normal.
final Future<?> future = executor.submit(new MyAudioProcessingRunnable())
// Schedule the cancelation to happen in 20 seconds.
executor.schedule(new Runnable() {
if (!future.isCancelled() && !future.isDone()) {
// Cancel and interrupt any blocking calls.
future.cancel(true);
}
}, 20, TimeUnit.Seconds);
IMPORTANT - You must have code in your MyAudioProcessingRunnable to support cancelation.

Workflow Design pattern combined with Task Pattern?

I'm currently working on an enterprise application that's performing a long non-linear tasks.
An abstraction of the workflow:
Gather neccessary information (can take minutes, but not always necessary)
Process data (always takes very long)
Notify several worker who post-process the result (in new tasks)
Now, I have created 2 services, that can solve step 1 and 2.
As the services shouldn't know of each other, I want to have a higher order Component that coordinates the 3 steps of an task. Think of it as an Callable which sends the task to service one, wakes up again when service 1 returnes an result, sends it to service 2, ..., sends final result to all post-processors and ends task.
But as it is likely to have 100'000s of queued tasks, I don't want to start 100'000s threads with task-control callables which even if being idle like 99.9% of the time still would be an massive overhead.
So got anybody an idea of controling this producer consumer queue-like pattern encapsulated in a task-object or somebody knows of an framework simplifying my concern?
Besides actor frameworks, I would suggest two main approaches that work with plain old Java:
Using an ExecutorService to which we submit tasks. The proper sequencing of steps can be synchronized using Future objects. The overall set of tasks can be synchronized using a Phaser a shown below.
Using the Fork/Join framework
Here is an example using a simple executor service. The Workflow class is given an executor and a phaser (a synchronization barrier). Each time the workflow is executed, it submits a new task for each of the steps (i.e., data collection, processing, and post-processing). Each task uses these phaser to indicate when it starts and stops.
public class Workflow {
private final ExecutorService executor;
private final Phaser phaser;
public Workflow(ExecutorService executor, Phaser phaser) {
this.executor = executor;
this.phaser = phaser;
}
public void execute(int request) throws InterruptedException, ExecutionException {
executor.submit(() -> {
phaser.register();
// Data collection
Future<Integer> input = executor.submit(() -> {
phaser.register();
System.out.println("Gathering data for call " + request);
phaser.arrive();
return request;
});
// Data Processing
Future<Integer> result = executor.submit(() -> {
phaser.register();
System.out.println("Processing call " + request);
Thread.sleep(5000);
phaser.arrive();
return request;
});
// Post processing
Future<Integer> ack = executor.submit(() -> {
phaser.register();
System.out.println("Notyfing processors for call " + request);
phaser.arrive();
return request;
});
final Integer output = ack.get();
phaser.arrive();
return output;
});
}
}
The caller object uses the phaser object to know when all subtasks (steps) have completed, before to shutdown the executor.
public static void main(String[] args) throws InterruptedException, ExecutionException {
final Phaser phaser = new Phaser();
final ExecutorService executor = Executors.newCachedThreadPool();
Workflow workflow = new Workflow(executor, phaser);
phaser.register();
for (int request=0 ; request<10 ; request++) {
workflow.execute(request);
}
phaser.arriveAndAwaitAdvance();
executor.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS);
}

How to shutdown CompletionService after completing currently executed tasks

I have something like this:
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
int i = 0;
while (i < 40) {
completionService.submit(getTask());
i++;
}
executor.shutdown();
System.out.println("SHUTDOWN");
After calling shutdown all submitted tasks are executed. If I call shutdownNow, then currently executed threads are throws java.lang.InterruptedException.
Is there are any way to wait currently executed tasks to complete and don't execute other submitted tasks?
shutdown() allows the currently submitted tasks to complete, but rejects new ones:
Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted.
If you want to wait in your main thread for the executor to shut down, you can invoke executor.awaitTermination(long timeout, TimeUnit unit):
Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.
If you want to allow the tasks that are currently running to complete, but discard the ones that are already submitted to the queue, you have a few choices:
cancelling the Futures with cancel(false):
Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run.
Returns:
false if the task could not be cancelled, typically because it has already completed normally; true otherwise
wrapping your Runnable/Callable with a custom CancellableRunnable/Callable (depending on what your getTask() returns):
class CancellableRunnable implements Runnable {
private final AtomicBoolean shouldRun;
private final Runnable delegate;
public CancellableRunnable(AtomicBoolean shouldRun, Runnable delegate) {
this.shouldRun = shouldRun;
this.delegate = delegate;
}
#Override
public void run() {
if (shouldRun.get()) {
delegate.run();
}
}
}
and the usage in your example:
AtomicBoolean shouldRun = new AtomicBoolean(true);
while (i < 40) {
completionService.submit(new CancellableRunnable(shouldRun, getTask()));
i++;
}
shouldRun.set(false);
executor.shutdown();
Yes, after you have called shutdown(), the executor will accept no new tasks. Next you call awaitTermination() to await running tasks completing.
If all you want is the first two results and then discard the other tasks, you can wait for the first two tasks to be completed then cancel the others, for example by calling shutdownNow if you don't need the completion service any longer.
Future<Boolean> result1 = copmletionService.take();
Future<Boolean> result2 = copmletionService.take();
completionService.shutdownNow();

ScheduledExecutorService and ThreadPoolTaskExecutor that interrupts tasks after a timeout

I Used ExecutorService that interrupts tasks after a timeout.I use a ScheduledExecutorService for this. First I submitted the thread and it once to begin immediately and retain the future that is created. After that i use ScheduledExecutorService as a new task that would cancel the retained future after some period of time.
//Start Spring executor to submit tasks
ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) ApplicationContextProvider.getApplicationContext().getBean("taskExecutor");
CompletionService completionService = new ExecutorCompletionService(taskExecutor);
//End Spring executor to submit tasks
// Start ScheduledExecutorService to submit returned future object to timeout
ScheduledExecutorService executor = Executors.newScheduledThreadPool(Integer.parseInt(config.getProperty("DBPOLLER_COREPOOLSIZE")));
final Future<String> future = completionService.submit(batchJob); // Submit actual task and get future
// submit future
executor.schedule(new Runnable() {
public void run() {
future.cancel(true);
}
}, dbPollerTimeOut, TimeUnit.MINUTES);
int count = taskExecutor.getActiveCount();
if (count == 0) {
taskExecutor.shutdown();
executor.shutdown();
finalExitStatus = 0;
break;
}
I have implemented the solution which is in below url:
ExecutorService that interrupts tasks after a timeout, it was working fine, until timeout, but once timeout happens, it cancels all theenter code here tasks i ThreadPool which is not acceptable. I need to cancel only tasks that are long running and reach timeout.
Any idea how to achieve this?
It is not clear what your CompletionService is, and you are submitting your batchJob on it, so it is hard to tell exact root cause of your problem. But ideal scenario of submitting few tasks and cancelling them after some time, is to use ScheduledExecutorService for both purposes.
So, can try submitting the batchJobon instance of ScheduledExecutorService i.e. executor.
final Future<String> future = executor.submit(batchJob); // Submit actual task and get future
EDIT UPDATE: Important change you SHOULD do in your code
I see that you are never stopping your ScheduledExecutorService which is wrong because resources it occupies will never be released until you stop it. So, your updated code should be as below:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(Integer.parseInt(config.getProperty("DBPOLLER_COREPOOLSIZE")));
final Future<String> future = executor.submit(batchJob); // Submit actual task and get future
executor.schedule(new Runnable() {
public void run() {
future.cancel(true);
executor.shutdownNow();
}
}, dbPollerTimeOut, TimeUnit.MINUTES);

Thread to ask for new tasks from executorservice

I currently have the main method which collects tasks. After the tasks are collected, the ExecutorService is being called with fixed thread pool size. The tasks are iterated and submitted to the executor.
But I need to refresh the tasks and if there is any new tasks available I am adding it to the executor. But if one of the thread is free without any tasks to be allocated from the queue, I want that thread to manually notify my main thread to refresh the events and submit to executor even before the manual refresh is happening from my end. How can i achieve this. Thanks
Sample Code
public class Sample{
Map<String, List<Integer>> tasks;
ThreadPoolExecutor executor;
public static void main(String[] args) {
executor = Executors.newFixedThreadPool(2);
tasks = Collections.synchronizedMap(new HashMap<String, List<Integer>>());
tasks = Tasks.refresh(); //This will get me a new set of data to be processed
invokeexecutor();
}
public void invokeexecutor(){
for(String key: tasks.keyset())
{
executor.submit(new TaskRunnable(tasks.get(key));
}
tasks.clear(); //Remove the allocated tasks from the collection
}
}
public class TaskRunnable implements Runnable{
public void run(){
//Do some logic
}
}
In this case I want my data in the tasks to be continuously refreshed after 10 seconds lets say or if any of the executor thread is free this refresh must happen and a new runnable mus tbe assinged to the thread.
But if one of the thread is free without any tasks to be allocated from the queue, I want that thread to manually notify my main thread to refresh the events and submit to executor even before the manual refresh is happening from my end. How can i achieve this.
There are a couple of ways you can achieve this easily. One way is to create the `ThreadPoolExecutor' yourself.
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
Then have a polling thread that watches the ThreadPoolExecutor class to determine if there are any free threads. Something like:
while (!Thread.currentThread().isInterrupted()) {
// sleep a bit
Thread.sleep(1000);
if (executor.getActiveCount() < 2) {
// add tasks here
}
}
A polling thread is a bit gross however. Another idea which is a bit simpler would be to use a fixed size queue of tasks and then always be trying to add the tasks to the list. This will block if the queue is full. Something like:
// create a limited blocking queue
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(10));
while (!Thread.currentThread().isInterrupted()) {
// add tasks here which will block if too many in the queue
}
You can try to override afterExecute method in ThreadPoolExecutor. It is called when a thread in a pool executed a task.
class MyThreadPoolExecutor extends ThreadPoolExecutor {
public MyThreadPoolExecutor {
super(/*Call one of TheadPoolExecutor constructors*/)
}
protected afterExecute(Runnable r, Throwable t) {
// Notify main thread here
}
}

Categories