Целесообразно ли добавлять задачи в BlockingQueue для ThreadPoolExecutor?

В JavaDoc для ThreadPoolExecutor неясно, допустимо ли добавлять задачи непосредственно в BlockingQueue , поддерживающую В документации говорится, что , вызывающий executor.getQueue () , «предназначен в первую очередь для отладки и мониторинга».

Я создаю ThreadPoolExecutor с помощью my own BlockingQueue . Я сохраняю ссылку на очередь, поэтому могу напрямую добавлять в нее задачи. Та же самая очередь возвращается функцией getQueue () , поэтому я предполагаю, что предупреждение в getQueue () относится к ссылке на резервную очередь, полученную с помощью моих средств.

Пример

Общий шаблон кода:

int n = ...; // number of threads
queue = new ArrayBlockingQueue(queueSize);
executor = new ThreadPoolExecutor(n, n, 1, TimeUnit.HOURS, queue);
executor.prestartAllCoreThreads();
// ...
while (...) {
    Runnable job = ...;
    queue.offer(job, 1, TimeUnit.HOURS);
}
while (jobsOutstanding.get() != 0) {
    try {
        Thread.sleep(...);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
}
executor.shutdownNow();

queue.offer () vs executor.execute ()

Насколько я понимаю, типичное использование - это добавление задач через executor.execute ( ) . Подход в моем примере выше имеет преимущество блокировки в очереди, тогда как execute () дает немедленный сбой, если очередь заполнена и отклоняет мою задачу. Мне также нравится, что отправка заданий взаимодействует с блокирующей очередью; мне это кажется более "чистым" производителем-потребителем.

Смысл добавления задач в очередь напрямую: Я должен вызвать prestartAllCoreThreads () , иначе рабочие потоки не будут запущены. При отсутствии других взаимодействий с исполнителем, ничто не будет контролировать очередь (проверка источника ThreadPoolExecutor подтверждает это). Это также подразумевает, что для прямой постановки в очередь ThreadPoolExecutor должен быть дополнительно настроен для> 0 основных потоков и не должен быть настроен так, чтобы разрешать тайм-аут основных потоков.

tl; dr

Учитывая ] ThreadPoolExecutor настроен следующим образом:

  • основных потоков> 0
  • основных потоков не разрешено время ожидания
  • основные потоки предварительно запущены
  • содержат ссылку на поддержку BlockingQueue исполнитель

Допустимо ли добавлять задачи непосредственно в очередь вместо вызова исполнителя. execute () ?

Связанный

Этот вопрос ( рабочие очереди производителя / потребителя ) аналогичен, но не касается прямого добавления в очередь.

18
задан Community 23 May 2017 в 12:22
поделиться