我的程序通过分而治之的方法搜索问题的解决方案(任何解决方案),使用递归和RecursiveTasks
实现:我为第一个分支执行任务除法,然后递归到第二个分支:如果第二个分支找到了解,那么我取消第一个分支,否则我等待它的结果。
这可能不是最佳选择。如果找到解决方案,一种方法是针对任何已启动的任务抛出异常。但是,我将如何取消所有已启动的任务?取消任务是否也取消所有子任务?
答案 0 :(得分:2)
由于无法取消线程的原因,框架无法取消任务。有关所有原因,请参阅Thread.stop()上的文档。任务可以锁定什么锁?它可以与哪些外部资源联系起来?所有相同的Thread.stop()原因也适用于任务(毕竟,任务在线程下运行。)您需要告诉任务停止,就像告诉线程停止一样。
我管理另一个使用分散 - 聚集技术的fork / join项目。我做取消或短路的方式是我创建的每个任务都传递一个具有
的对象(PassObject)protected volatile boolean stop_now = false;
以及停止任务的方法
protected void stopNow() {stop_now = true; }
每个任务定期检查stop_now,当为true时,它会正常结束任务。
不幸的是,stop_now需要是volatile,因为另一个线程将设置它。如果经常检查,这会增加很多开销。
如何在另一个任务中设置此字段有点棘手。我创建的每个任务还包含对每个其他任务的引用数组的引用
int nbr_tasks = nbr_elements / threshold;
// this holds the common class passed to each task
PassObject[] passList = new PassObject[nbr_tasks];
for (int i = 0; i < nbr_tasks; i++)
passList[i] = new PassObject( passList,… other parms);
一旦形成列表,我在passList中fork()每个对象。每个PassObject都包含对数组的引用passList,它包含对传递给每个任务的每个对象的引用。因此,每个任务都知道其他任务,当一个任务想要取消其他任务时,它只需调用cancelOthers方法并引用passList。
private void cancelOthers (PassObject[] others) {
// tell all tasks to stop
for (int i = 0, max = others.length; i < max; i++)
others[i].stopNow();
如果您正在使用Java8,那么您可以使用CountedCompler类而不是RecusiveTask进行分散 - 聚集。对于Java7或者如果您仍想使用RecursiveTask,则递归中的第一个任务需要创建一个AtomicBoolean字段(AtomicBoolean stop_now = new AtomicBoolean(false);)并在它创建的每个新RecursiveTask中包含对该字段的引用。使用递归,您不知道在开始时您需要多少级别的任务。 同样,您需要在代码中定期检查布尔值中的true,如果为true,则优雅地结束任务。
以上只是一个如何取消的提示。每个应用程序都不同。我的工作对我的应用程序有效 - 但逻辑是一样的。在任务可以设置的每个任务中都需要一些共同的东西,而其他任务都可以看到。
我会添加更多代码,但代码插入只是一次占用一行而且不实用。
答案 1 :(得分:2)
您可以使用任务管理器的简单方法。例如:
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);
}
}
}
}
任务:
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);
}
}