线程中的异常

时间:2009-10-20 17:08:16

标签: java multithreading

我制作了一个多线程程序。在其中,主线程启动10个线程,但问题是当其中一个线程发生异常时,整个应用程序都会停止。

  1. 但我希望每当在一个线程中发生异常时,只有该线程应该停止并且其他线程继续工作。我怎么能这样做?

  2. 其次,我希望只有在所有10个线程完成后才能停止主线程。我怎么能这样做?

5 个答案:

答案 0 :(得分:4)

您可以使用ExecutorService(包含多个线程)通过调用submit()来处理您的各个工作项。 submit方法返回一个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.
  }
}

答案 1 :(得分:3)

在main方法结束时,您应该在每个已启动的线程上调用join

顺便说一下:如果你想处理线程的异常,你可以使用Thread.setDefaultUncaughtExceptionHandler()

答案 2 :(得分:1)

使用try / catch all

进行环绕
public void run() {
    try {
        ....
    } catch( Exception e ){}
}

虽然我最好试着找出这些例外的原因。

答案 3 :(得分:1)

对于#1,如果这是您的预期目标,您应该考虑如何处理该异常以及您期望的异常类型。如果这些是应用程序错误,您可以确定一种更有用的方法来捕获单个线程级别的异常,并将重要信息反馈给父线程。或者,管理线程池的解决方案可能是更好的方法,就像@Adamski所指出的那样,就像ExecutorSerivce ThreadPoolExecutor的实现一样,但是你需要理解异常以及是否可以通过一些额外的逻辑来防止它们如果没有,那么有一个更好的方法来有效地管理你的工作是可行的。

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

对于#2,join()或使用线程池来管理它们。

答案 4 :(得分:0)

关于你的第一点,我建议你在抛出异常时优雅地退出一个线程,也就是说,在线程中捕获它(而不是让它冒泡到jvm)。