我有一个包含 40000 条记录的列表,需要在 for 循环中进行处理。因为我有一个双处理器系统。我创建了一个固定线程池,如下所示:
int threads = Runtime.getRuntime().availableProcessors(); ExecutorService service = Executors.newFixedThreadPool(threads);
并划分了我的
ArrayList
分成两个子列表。对于每个子列表,我都创建了一个Callable
执行相同的功能(涉及迭代子列表并进行一些处理)并返回Future
对象。我提交了这两个
Callable
使用executorServiceObject.submit(callable)
并添加返回的Future
对象进入我的列表Future
对象
这是我的问题:
我写了一个System.Out.printLn("Processed Item" +item.id) // consider item as the name of reference variable for current iteration
有一段时间一切都很好,我可以看到两个线程同时工作。但一段时间后,其中一个线程已停止处理。只有一个线程正在运行。 (我知道这一点是因为我可以在控制台上看到给予线程 2 的 id 不再被打印)。
有谁知道这是怎么发生的吗?我的意思是为什么 ExecutorService 停止运行第二个线程。
感谢您提前提供的帮助。
添加示例代码,就像我之前应该做的那样:
public List<Output> processInputs(List<Input> inputs)
throws InterruptedException, ExecutionException {
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService service = Executors.newFixedThreadPool(threads);
List<Future<Output>> futures = new ArrayList<Future<Output>>();
for (final Input input : inputs) {
Callable<Output> callable = new Callable<Output>() {
public Output call() throws Exception {
Output output = new Output();
// process your input here and compute the output
return output;
}
};
futures.add(service.submit(callable));
}
service.shutdown();
List<Output> outputs = new ArrayList<Output>();
for (Future<Output> future : futures) {
outputs.add(future.get());
}
return outputs;
最佳答案
Everything was fine for some time and i could see two threads working simultaneously. But after some time, one of the threads have stopped processing. Only one thread is running. (I know this because i can see on the console that the id's given to thread 2 are not being printed anymore).
我怀疑你的处理线程抛出了异常。 Future.get()
方法可以抛出 ExecutionException
"if the computation threw an exception" .
// the following might throw an exception if the background job threw
outputs.add(future.get());
如果您的“处理您的输入”代码抛出了 NPE、IOException 等,则 Callable
会抛出该异常。并存储在Future
中所以它可以被 get()
抛出方法,但包含在 ExecutionException
中。这很有用,因此正在等待的线程可以获取并处理(记录等)后台线程抛出的异常。
而不是仅仅拥有您的 processInputs(...)
方法向调用者抛出异常,它可能会丢失,我会在您的 while
中执行类似以下操作循环:
try {
outputs.add(future.get());
} catch (InterruptedException ie) {
// always a good pattern if the thread that is waiting was interrupted
Thread.currentThread().interrupt();
return;
} catch (ExecutionException ee) {
// somehow log the error
logger.error("Computation failed to process", ee);
// now continue and get the next future in the list
}
如果你没有捕获并妥善处理这个问题ExecutionException
那么处理异常也会杀死调用 processInputs(...)
的线程.
关于java - ExecuterService 停止处理两个线程中的一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44110677/