2009-10-20 94 views
2

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

  1. 但我想,只要一个异常发生在一个线程中,只有线程应该被停止,其他线程继续工作。我怎样才能做到这一点?

  2. 其次,我希望主线程应该在所有10个线程完成后才会停止。我怎样才能做到这一点?

回答

4

你可以使用一个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. 
    } 
} 
1

环绕与try/catch语句的所有

public void run() { 
    try { 
     .... 
    } catch(Exception e){} 
} 

虽然我会更好地尝试为那些异常的原因。

0

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

1

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

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

#2,加入(),或使用一个线程池来管理它们。