Java 如何在将来取消生成的可调用项。取消?
我有一个Java 如何在将来取消生成的可调用项。取消?,java,multithreading,Java,Multithreading,我有一个ExecutorService,我向其提交nCallables。在这些nCallables中,我生成了新的Callables,它们被提交到相同的ExecutorService。 当我在其各自的Future.get()中的前n个可调用的s上遇到java.util.concurrent.TimeoutException时,我会对该可调用的执行Future.cancel(true)。我还需要取消我提交的任务,因为这些任务已被取消Callables 我可以这样做的一种方法是将生成的Callabl
ExecutorService
,我向其提交nCallable
s。在这些nCallable
s中,我生成了新的Callable
s,它们被提交到相同的ExecutorService
。
当我在其各自的Future.get()
中的前n个可调用的s上遇到java.util.concurrent.TimeoutException
时,我会对该可调用的执行Future.cancel(true)
。我还需要取消我提交的任务,因为这些任务已被取消Callable
s
我可以这样做的一种方法是将生成的Callable
存储在调用堆栈中某个位置的列表映射中,在取消Callable
的同时,使用它查找其子项并取消它们。但这对我来说似乎不是一个很好的解决方案,因为取消的逻辑应该在更近的地方
有没有更好的方法可以给我这种灵活性
当我在前n个可调用项各自的Future.get()上遇到java.util.concurrent.TimeoutException时,我会对该可调用项执行Future.cancel()。由于这些已取消的可调用项,我还需要取消我提交的任务
调用future.cancel(false)
时,仅当作业尚未运行时,才会停止作业的执行。在这种情况下,您不会有问题,因为没有创建“子作业”
因此,我假设您谈论的是未来。cancel(true)
,如果作业已经在运行,它将中断线程。必须认识到,此中断只影响引发InterruptedException
的少数方法,如Thread.sleep(…)
,obj.wait(…)
等。。否则,您将需要测试代码中的中断标志。例如:
while (!Thread.currentThread().isInterrupted()) {
...
}
我要做的是让你的每一份工作都保留一份它产生的未来的“子工作”的列表。当它捕捉到一个中断异常
或者当它注意到它的线程中断标志已经设置时,它就可以对它分叉的所有作业调用future.cancel(true)
比如:
final List<Future<...>> subJobs = new ArrayList<>();
...
while (true) {
if (Thread.currentThread().isInterrupted()) {
cleanupSubJobs(subJobs);
break;
}
try {
Thread.sleep(...);
} catch (InterruptedException ie) {
// always a good pattern
Thread.currentThread.interrupt();
cleanupSubJobs(subJobs);
return;
}
...
if (weNeedSubJob) {
subJobs.add(threadPool.submit(...));
}
}
...
private void cleanupSubJobs(List<Future<...>> subJobs) {
for (Future<...> subJob : subJobs) {
subJob.cancel(true);
}
}
final List subbobs=new ArrayList();
...
while(true){
如果(Thread.currentThread().isInterrupted()){
清理子作业(子作业);
打破
}
试一试{
睡眠(…);
}捕获(中断异常ie){
//总是一个好的模式
Thread.currentThread.interrupt();
清理子作业(子作业);
返回;
}
...
如果(weNeedSubJob){
subbobs.add(threadPool.submit(…);
}
}
...
私有无效清除子作业(列表子作业){
for(未来主题:主题){
subJob.cancel(true);
}
}
似乎根可调用的
应该协调其派生的可调用的
s。因此,当它接收到取消中断时,它应该在其“子对象”上调用cancel
。注意让callablea在同一池中阻塞它们自己的callables。这就是死锁的秘诀。@SotiriosDelimanolis您的意思是说我应该在根目录中调用一个try-catch块来检测ThreadInterruptedException以进行清理吗?Future.cancel()是否确保触发此异常?是的,只是一般情况。例如,请参阅。Future#cancel
通常通过中断执行器服务中执行工作的线程来实现。你应该听听,并把它传播给孩子们。谢谢你的回答。在我的第二级可调用函数中引入无限while循环似乎不是一个简单的方法。它基本上将subbob提交到线程池,然后等待subbob返回。然而,我看到Future.get()抛出了一个InterruptedException。如果我在第二级Callable中发现了这一点,我可以取消那里的所有子任务。