2015-02-22 2 views
0

ThreadPoolExecutor наследует метод submit(Callable<T> task).
Конструктор ThreadPoolExecutor принимает экземпляр BlockingQueue<Runnable>. Эта блокирующая очередь может содержать только Runnable экземпляров.
Javadoc для ThreadPoolExecutor конструктора говорит:submit (Callable <T> задача) метод в ThreadPoolExecutor

Очереди использовать для хранения задач, прежде чем они будут выполнены. В этой очереди будут выполняться только задачи Runnable, представленные методом execute.

Итак, мой вопрос: как поставлены задачи через submit(Callable<T> task)?

ответ

0

Он упакован в Runnable (в частности, RunnableFuture) с использованием newTaskFor(Callable). См. source code.

0

Вы можете найти объяснение в queuing section of the ThreadPoolExecutor documentation:

Queuing

Любой BlockingQueue может быть использован для передачи и держать представленные задачи. Использование этой очереди взаимодействует с размером пула:

  • Если работает меньше потоков corePoolSize, Executor всегда предпочитает добавлять новый поток, а не выполнять очередность.
  • Если запущено corePoolSize или больше потоков, Executor всегда предпочитает очередность запроса, а не добавление нового потока.
  • Если запрос не может быть поставлен в очередь, создается новый поток, если это не будет превышать maximumPoolSize, и в этом случае задача будет отклонена.

Существуют три основные стратегии для организации очередей:

  1. Прямые передачи обслуживания. Хорошим выбором по умолчанию для рабочей очереди является SynchronousQueue, который снимает задачи с потоками, не удерживая их. Здесь попытка очереди в задаче будет терпеть неудачу, если потоки не будут доступны для ее запуска, поэтому будет создан новый поток. Эта политика позволяет избежать блокировок при обработке наборов запросов, которые могут иметь внутренние зависимости. Прямые передачи обслуживания обычно требуют неограниченных максимальных значений, чтобы избежать отклонения новых отправленных задач. Это, в свою очередь, допускает возможность неограниченного роста потоков, когда команды продолжают поступать в среднем быстрее, чем они могут быть обработаны.

  2. Неограниченные очереди. Использование неограниченной очереди (например, LinkedBlockingQueue без предопределенной емкости) заставит новые задачи ждать в очереди, когда все потоки corePoolSize заняты. Таким образом, не более, чем потоки corePoolSize будут созданы. (И значение maximumPoolSize поэтому не имеет никакого эффекта.) Это может быть целесообразно, когда каждая задача полностью независима от других, поэтому задачи не могут повлиять на выполнение других действий; например, на сервере веб-страниц. Хотя этот стиль очередей может быть полезен для сглаживания временных запросов, он допускает возможность неограниченного роста очереди работы, когда команды продолжают поступать в среднем быстрее, чем они могут быть обработаны.

  3. Ограниченные очереди. Ограниченная очередь (например, ArrayBlockingQueue) помогает предотвратить исчерпание ресурсов при использовании с конечными максимальными значениямиPoolSizes, но может быть сложнее настроить и контролировать. Размеры очереди и максимальные размеры пула могут быть проданы друг для друга: использование больших очередей и небольших пулов минимизирует использование ЦП, ресурсы ОС и перераспределения контекста, но может привести к искусственно низкой пропускной способности. Если задачи часто блокируются (например, если они связаны с I/O), система может планировать время для большего количества потоков, чем вы в противном случае разрешаете. Использование небольших очередей обычно требует больших размеров пула, что повышает производительность процессоров, но может столкнуться с неприемлемыми накладными расходами на планирование, что также снижает пропускную способность.

Некоторые примеры можно найти в Executors классе, который предлагает методы для создания нескольких типов ThreadPoolExecutor.

+0

Метод Submit() принимает объект, подлежащий вызову, тогда как очередь блокировки может содержать только выполняемые объекты. – Anuj

 Смежные вопросы

  • Нет связанных вопросов^_^