主要过程:
int cpus = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(cpus);
List<Callable<Object>> todo = new ArrayList<Callable<Object>>(lines.size());
for (int r = 0; r < lines.size(); r++) {
String filename = r + 1 + "";
todo.add(Executors.callable(new AppConsole(filename, lines.get(r))));
}
List<Future<Object>> answers = executor.invokeAll(todo);
AppConsole类实现了Runnable,而overriden run方法如下:
public void run() {
try{
} catch (SecurityException exception) {
exception.printStackTrace();
} catch (FileNotFoundException exception) {
exception.printStackTrace();
} catch (IOException exception) {
exception.printStackTrace();
} catch (SAXException exception) {
exception.printStackTrace();
} catch (Exception exception) {
exception.printStackTrace();
} finally {
if (output != null) {
output.close();
}
}
}
}
由于从其中一个线程抛出连接超时异常,主进程被挂起并无法完成。现在我可以看到cpu使用率下降到0%,内存消耗在挂起时保持在同一级别。
有人可以帮我解决这个问题吗?至少,帮我完成主要工艺?
答案 0 :(得分:3)
抛出异常会释放任务和主线程。 ExecutorService将异常抛出视为另一个返回值,并且处理它时没有问题。
主线程只会阻止等待您的某个任务完成。我会查看仍处于活动状态的任务/线程,看看他们正在做什么,例如也许他们还没有超时。
答案 1 :(得分:0)
你只需要添加:
executor.shutdown();
等待所有任务完成并关闭所有线程后,应用程序将在此之后退出。 请参阅newFixedThreadPool的javadoc:
创建一个重用固定数量的线程的线程池 关闭共享的无界队列。在任何时候,最多nThreads线程 将是主动处理任务。如果提交了其他任务 当所有线程都处于活动状态时,它们将在队列中等待直到a 线程可用。如果任何线程由于故障期间终止而终止 在关机之前执行,如果需要,新的将取代它 执行后续任务。池中的线程将一直存在 它是明确关闭的。
答案 2 :(得分:0)
你可以使用带有显式超时值的invokeAll的替代版本:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
invokeAll(Collection<? extends Callable<T>> tasks,
long timeout,
TimeUnit unit)
通过这种方式,您可以强制所有任务在30秒后超时。然后你可以检查返回的期货,看看哪些已经完成。