2010-02-25 3 views
15

Я хотел бы иметь ScheduledThreadPoolExecutor, который также останавливает последний поток, если нет работы, и создает (и сохраняет потоки в течение некоторого времени), если есть новые задачи. Но как только больше нет работы, он должен снова отказаться от всех потоков.ScheduledThreadPoolExecutor и corePoolSize 0?

Я наивно создал его как new ScheduledThreadPoolExecutor(0), но, как следствие, нить ни разу не создавалась, ни какая-либо запланированная задача никогда не выполнялась.

Может ли кто-нибудь сказать мне, могу ли я достичь своей цели, не написав свою собственную обертку вокруг ScheduledThreadpoolExecutor?

Заранее благодарен!

+1

Похоже, вы хотите что-то, что создает и срывает потоки, как «ExecutorService» из «Executors.newCachedThreadPool()», за исключением того, что вы хотели бы реализовать интерфейс «ScheduledExecutorService» вместо «ExecutorService» интерфейс. Это точное резюме? –

+0

Собственно, да, это довольно точное резюме. –

ответ

14

На самом деле вы можете сделать это, но его неочевидным:

  • Создать новую ScheduledThreadPoolExecutor
  • В конструкторе установить основные нити, чтобы максимальное количество потоков, которые вы хотите
  • установить KeepAliveTime исполнителя
  • и наконец, позволить основные темы тайм-аут

    m_Executor = new ScheduledThreadPoolExecutor (16,null); 
    m_Executor.setKeepAliveTime (5, TimeUnit.SECONDS); 
    m_Executor.allowCoreThreadTimeOut (true); 
    

    Это работает только с Java 6, хотя

+0

Огромное спасибо, это звучит совершенно точно, что мне нужно. –

7

Я подозреваю, что ничего из java.util.concurrent не сделает это за вас, просто потому, что если вам нужна служба исполнения по расписанию, у вас часто возникают повторяющиеся задачи. Если у вас есть повторяющаяся задача, тогда обычно имеет смысл просто поддерживать один и тот же поток и использовать его для следующего повторения задачи, вместо того, чтобы срывать нить и создавать новую при следующем повторении ,

Конечно, запланированный исполнитель может быть использован для вставки задержек между нерегулярными задачами или может использоваться в тех случаях, когда ресурсы настолько скудны, и повторение настолько редко, что имеет смысл разорвать все ваши потоки до тех пор, пока приходит новая работа. Итак, я вижу случаи, когда ваше предложение определенно имеет смысл.

Чтобы реализовать это, я хотел бы попытаться обернуть пул кешированных потоков из Executors.newCachedThreadPool вместе с однопотоковой службой планового исполнителя (то есть new ScheduledThreadPoolExecutor(1)). Задачи могут быть запланированы через запланированную службу-исполнитель, но запланированные задачи будут завернуты таким образом, что вместо того, чтобы выполнить однопотоковый запланированный исполнитель, однопоточный исполнитель передаст их в пул кэшированных потоков для фактических выполнение.

Этот компромисс даст вам максимум одного потока, если нет абсолютно никакой работы, и это даст вам столько потоков, сколько вам нужно (в пределах вашей системы, конечно), когда есть партии работы.

+0

Спасибо за подробный ответ. На самом деле, я использую ScheduledThreadPool для отложенных операций, а не для повторных действий. И большинство действий - одноразовые действия, и мне бы не хотелось создавать Thread каждый раз, и я также ненавидел бы явное совместное использование ScheduledExecutorService вручную между различными классами, которые должны это делать. –

8

Чтение ThreadPoolExecutor Javadocs можно предположить, что решение Alex V в порядке. Однако это приведет к ненужному созданию и уничтожению потоков, не что иное, как обналиченный пул потоков. ScheduledThreadPool не предназначен для работы с переменным числом потоков. Посмотрев на источник, я уверен, что вы в конечном итоге создадите новый поток почти каждый раз, когда вы отправляете задание. Решение Joe должно работать, даже если вы ТОЛЬКО отправляете отложенные задачи.

PS.Я бы отслеживал ваши потоки, чтобы убедиться, что вы не тратите ресурсы в своей текущей реализации.

5

Эта проблема является известной ошибкой в ​​ScheduledThreadPoolExecutor (Bug ID 7091003) и исправлена ​​в Java 7u4. Хотя looking at the patch, исправление заключается в том, что «хотя бы один поток запущен, даже если corePoolSize равен 0.»