Могут ли два ExecutorServices совместно использовать пул потоков?

У меня есть набор записей для обработки, и обработка может быть распараллелена, поэтому я создал ExecutorService (через Исполнители # newCachedThreadPool ()). Обработка отдельной записи сама по себе состоит из параллелизируемых шагов, поэтому я хотел бы использовать другой ExecutorService. Есть ли простой способ заставить этот новый пул использовать тот же базовый пул потоков? Это вообще желательно? Спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
0
3 873
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Можете ли вы просто передать ссылку на существующий ExecutorService своим рабочим объектам?

public class Task implements Runnable {
    private final ExecutorService threadPool;
    private final SubTask[] subtasks;

    public Task(ExecutorService threadPool) {
        this.threadPool = threadPool;
        this.subtasks = createSubtasksIGuess();
    }

    public void run() {
        for(SubTask sub : subtasks)
            threadPool.submit(sub);
    }
}
Ответ принят как подходящий

Чтобы ответить на ваш вопрос: нет, два объекта ExecutorServiceне могу совместно используют пул потоков. Однако вы можете совместно использовать ExecutorService между своими объектами или, в качестве альтернативы, создать несколько исполнителей, если это необходимо, хотя это менее рекомендуется.

Лучшее решение: поделитесь Executor между своими объектами.

Краткий ответ: Нет.

Более длинный ответ: для этого вам понадобится собственная реализация. ExecutorService - это интерфейс, и AbstractExecutorService довольно легко реализовать. Если вы хотите, чтобы два ExecutorService совместно использовали один пул ThreadPool (например, с разным максимальным значением активного потока), вы можете использовать шаблон прокси, чтобы ThreadPool совместно использовал ExecutorService.

Спасибо! Здесь был бы красивый образец прокси. Дублирование кода Дуга Ли для подключаемого пула потоков было бы слишком подвержено ошибкам.

Michael Deardeuff 24.11.2009 08:28

(В моем случае мне нужно было дождаться завершения всех задач для каждого Executor. То есть использовать методы shutdown () / awaitTermination ())

Michael Deardeuff 24.11.2009 09:23

Для этого есть несколько веских причин, например отдельные границы и метрики для каждой очереди. AFAIK, Cassandra 2.1 немало выиграла от использования реализации службы исполнителя с общим пулом потоков; код находится в https://github.com/apache/cassandra/blob/trunk/src/java/org/apache/cassandra/concurrent/SEPExecutor.java.

Конечно, исходная проблема требует прямого использования API-интерфейсов задач fork / join, которые доступны в Java 7.

Cagatay 18.12.2014 20:00

Другой вариант использования, который у меня был недавно, - это иметь пул с одним потоком с одной очередью, но с двумя исполнителями, один из которых использует AbortPolicy, а другой CallerRunsPolicy.

Graham 11.12.2020 16:25

Другие вопросы по теме