如果任何线程中发生异常,则中断所有线程 [英] Interrupt all threads if an exception occurs in any
问题描述
我有一个方法名称 someTask
,我必须调用100次,并且使用如下所示的异步编码。
I have a method name someTask
that I have to invoke 100 times and I am using asynchronous coding as below.
for (int i = 0; i < 100; i++) {
futures.add(CompletableFuture.supplyAsync(
() -> { someTask(); },
myexecutor
));
}
如果在执行 someTask()时任何线程上发生异常
我想中断所有当前线程,也要停止将来的线程执行。最好的处理方法是什么?
If an exception occurs on any thread while executing someTask()
I want to interrupt all the current threads and also stop future threads from executing. What is the best way to handle this?
更新:
我正在使用 ThreadPoolTaskExecutor
推荐答案
有很多方法可以做到这一点,并且都取决于确切的用例。但是,所有方式(我想说)都有一个共同点:您必须以可控的方式结束任务。您不能只是即时终止,执行任务,因为这可能导致数据不一致和其他问题。这通常是通过检查一些标志来完成的,例如 Thread.isInterrupted()
,如果它表示执行将被取消,则手动结束执行。您也可以使用一个自定义标志,该标志将显示:
There are many ways to do that and all depend on the exact use case. But all ways (I'd say) have one thing in common: you'll have to end the tasks in a controlled manner. You can't just "instant-terminate" the execution of a task because this could lead to inconsitent data and other problems. This is usually done by checking some flag, e.g. Thread.isInterrupted()
, and ending the execution manually if it's signaling that the execution shall cancel. You can use a custom flag as well, which I'll show:
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
class Main {
static final ExecutorService executor = Executors.newCachedThreadPool();
// just dummy stuff to simulate calculation
static void someStuff(AtomicBoolean cancel) {
if (cancel.get()) {
System.out.println("interrupted");
return;
}
System.out.println("doing stuff");
for (int i = 0; i < 100_000_000; i++) {
Math.sqrt(Math.log(i));
}
}
static void someTask(AtomicBoolean cancel) {
someStuff(cancel);
someStuff(cancel);
someStuff(cancel);
}
public static void main(String[] args) {
final Set<CompletableFuture<?>> futures = new HashSet<>();
final AtomicBoolean cancel = new AtomicBoolean();
for (int i = 0; i < 10; i++) {
futures.add(CompletableFuture.supplyAsync(
() -> {someTask(cancel); return null;}, executor
));
}
futures.add(CompletableFuture.supplyAsync(() -> {
try {
throw new RuntimeException("dummy exception");
}
catch (RuntimeException re) {
cancel.set(true);
}
return null;
}));
futures.forEach(cf -> cf.join());
executor.shutdownNow();
}
}
请注意,最终任务正在抛出异常并通过设置异常来处理将取消
标记为 true
。其他所有任务将通过定期检查来查看。如果标志发出信号,它们将取消执行。如果您将抛出异常的任务注释掉,则所有任务都将正常完成。
Notice that the final task is throwing an exception and handles it by setting the flag cancel
to true
. All the other tasks will see that by checking it periodically. They will cancel their execution if the flag signals it. If you comment out the exception-throwing task, all tasks will just finish normally.
请注意,此方法与所使用的执行程序无关。
Note that this approach is independent of the executor used.
这篇关于如果任何线程中发生异常,则中断所有线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!