我制作了一个多线程程序。其中,主线程启动10个线程,但问题是每当其中一个线程出现异常时,整个应用程序就会停止。线程异常
但我想,只要一个异常发生在一个线程中,只有线程应该被停止,其他线程继续工作。我怎样才能做到这一点?
其次,我希望主线程应该在所有10个线程完成后才会停止。我怎样才能做到这一点?
我制作了一个多线程程序。其中,主线程启动10个线程,但问题是每当其中一个线程出现异常时,整个应用程序就会停止。线程异常
但我想,只要一个异常发生在一个线程中,只有线程应该被停止,其他线程继续工作。我怎样才能做到这一点?
其次,我希望主线程应该在所有10个线程完成后才会停止。我怎样才能做到这一点?
你可以使用一个ExecutorService(包含多个线程)调用提交处理工作的各个项目()。提交方法返回一个Future,它将封装处理结果或抛出的任何异常。换句话说,如果发生异常,ExecutorService
内的线程将不会终止。
例
首先创建一个包含多个线程的执行服务:
ExecutorService execService = Executors.newFixedThreadPool(5);
定义的工作,我们希望提交的Callable
项目:
public class MyWorkItem implements Callable<Integer> {
public Integer call() throws Exception {
int result = new Random().nextInt(5);
// Randomly fail.
if (result == 0) {
throw new IllegalArgumentException("Fail!");
}
return result;
}
}
提交为执行者服务做一些工作,并将Future<Integer>
存储为每个Callable<Integer>
。
List<Future<Integer>> futures = new LinkedList<Future<Integer>>();
for (int i=0; i<10; ++i) {
futures.add(execService.submit(new MyWorkItem()));
}
现在遍历试图检索每个工作项目的结果(我们可以使用这个CompletionService
)期货。
for (Future<Integer> future : futures) {
try {
Integer result = future.get();
} catch(Exception ex) {
// Handle exception.
}
}
在主方法结束时,您应该在每个启动的线程上调用join
。
顺便说一句:如果你想处理您的线程的例外,可以使用Thread.setDefaultUncaughtExceptionHandler()
环绕与try/catch语句的所有
public void run() {
try {
....
} catch(Exception e){}
}
虽然我会更好地尝试为那些异常的原因。
关于你的第一点,我会建议你在抛出异常时优雅地退出一个线程,也就是说,在线程内捕获它(并且不要让它冒泡到jvm)。
对于#1,如果这是您的预期目标,则应考虑您如何处理该异常以及您期望的异常类型。如果这些是应用程序故障,则可以确定一种更有用的方法来捕获单个线程级别的异常,并将重要信息反馈给父线程。另外一个为你管理线程池的解决方案可能是@Adamski指出的一个更好的方法,就像ExecutorServce ThreadPoolExecutor的实现一样,但是你需要了解异常,以及是否可以用一些额外的逻辑来阻止它们如果没有,那么有效管理工作的更好方式就是要走的路。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
#2,加入(),或使用一个线程池来管理它们。