Java ThreadPoolExexecutor с использованием потоков и Callables - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть класс, который реализует Callable, и у него есть метод, который переопределяет call и возвращает Long.

Я создаю List из Callable<Long> как

List<Callable<Long>> callables = new ArrayList<>();
for (File fileEntry : folder.listFiles()) {
    callables.add(new DataProcessor(fileEntry));

У меня есть

ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(10);

, и я звоню

threadPoolExecutor.invokeAll(callables)
    .stream()
    .map(future -> {
        try {
            return future.get();
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
        })
        .collect(Collectors.toLong(/* what goes here? */));

Я хочу суммировать все возвращаемые значения из future.get().

Кроме того, так как я вызываю invokeAll, мне все еще нужно завершить работу на Executor?

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Вы можете использовать Stream.mapToLong, чтобы отобразить future.get как LongStream, а затем найти sum потока как:

long sum = threadPoolExecutor.invokeAll(callables)
            .stream()
            .mapToLong(future -> {
                try {
                    return future.get();
                } catch (Exception e) {
                    throw new IllegalStateException(e);
                }
            }) // LongStream
            .sum(); // sum of the stream

Примечание : Это упрощает цепочки вызовов потокового API, используя Collectors.summingLong.Это позволяет избежать создания избыточных временных объектов при обходе коллекции.

В стороне : Вы также можете collect ваши Callable s как:

List<Callable<Long>> callables = fileList.stream()
                                         .map(fileEntry -> new DataProcessor(fileEntry))
                                         .collect(Collectors.toList());

, так как я вызываю invokeAll, мне все еще нужно завершить работу на Executor?

Да, вам придется выключить ExecutorService.Вы можете также подтвердить статус того же самого, используя isShutDown() API как:

System.out.println(threadPoolExecutor.isShutdown()); // would return false
0 голосов
/ 24 декабря 2018

То, что вам нужно, это Collectors.summingLong:

.collect(Collectors.summingLong(r -> r));

Где r -> r - это просто ToLongFunction, что составляет long от каждого Long, возвращаемого вашими Callable с.

Кроме того, так как я вызываю invokeAll, мне все еще нужно отключить Executor?

ExecutorService.invokeAll не документирует автоматическое отключение.Так что вам нужно будет выключить его самостоятельно

...