In a Java 7+ ForkJoinPool, is it possible to cancel a task and all subtasks?
fork-join, java, java.util.concurrent
Solution
You can use the simple approach with task manager. For example:
public class TaskManager<T> {
private List<ForkJoinTask<T>> tasks;
public TaskManager() {
tasks = new ArrayList<>();
}
public void addTask(ForkJoinTask<T> task) {
tasks.add(task);
}
public void cancelAllExcludeTask(ForkJoinTask<Integer> cancelTask) {
for (ForkJoinTask<T> task : tasks) {
if (task != cancelTask) {
task.cancel(true);
}
}
}
public void cancelTask(ForkJoinTask<Integer> cancelTask) {
for (ForkJoinTask<T> task : tasks) {
if (task == cancelTask) {
task.cancel(true);
}
}
}
}
And the task:
public class YourTask extends RecursiveTask<Integer> {
private TaskManager<Integer> taskManager;
@Override
protected Integer compute() {
// stuff and fork
newTask.fork();
// do not forget to save in managers list
taskManager.addTask(newTask);
// another logic
// if current task should be cancelled
taskManager.cancelTasks(this);
// or if you have decided to cancel all other tasks
taskManager.cancelAllExcludeTask(this);
}
}
Problem
My program searches for a solution (any solution) to a problem through a divide-and-conquer approach, implemented using recursion and `RecursiveTasks`'s: I fork a task for the first branch of the division, then recurse into the second branch: if the second branch has found a solution, then I cancel the first branch, otherwise I wait for its result. This is perhaps not optimal. One approach would be for any of the launched tasks to throw an exception if a solution is found. But then, how would I cancel all the launched tasks? Does cancelling a task also cancel all sub-tasks?