java - ExecuterService 停止处理两个线程中的一个

标签 java multithreading concurrency executorservice java.util.concurrent

  1. 我有一个包含 40000 条记录的列表,需要在 for 循环中进行处理。因为我有一个双处理器系统。我创建了一个固定线程池,如下所示:

    int threads = Runtime.getRuntime().availableProcessors(); ExecutorService service = Executors.newFixedThreadPool(threads);

  2. 并划分了我的ArrayList分成两个子列表。对于每个子列表,我都创建了一个 Callable执行相同的功能(涉及迭代子列表并进行一些处理)并返回 Future对象。

  3. 我提交了这两个 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/

相关文章:

java - 如何释放 Swingworker 分配的内存?

scala - STM 与 AKKA 的并发

java - 使用常规 HashMap 双重检查锁定

java - 如何将 Javascript 中的日期与语言环境进行比较

java - 在 Java 中多次询问用户输入

android - onRetainNonConfigurationInstance 具有多个线程?

python - 如何在 APScheduler 中使用 Tornado?

java - 为什么来自 'Concurrency in practice' 的 CooperatingNoDeadlock 使用与同一监视器的双同步?

java - 如何持久化 java.util.Currency 之类的类?

java - 是否可以在 JavaFX 中创建动态 Bindings.OR?