Если бы это был я, я бы предпочел использовать Executor#execute()
вместо Queue#offer()
, просто потому, что я уже использую все остальное, начиная с java.util.concurrent
.
Ваш вопрос хороший, и он задетменя заинтересовало, поэтому я взглянул на источник для ThreadPoolExecutor#execute()
:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
Мы можем видеть, что выполняются сами вызовы offer()
в очереди работы, но не раньше, чем делаются некоторые приятные, вкусные манипуляции с пуломесли необходимо.По этой причине я думаю, что было бы целесообразно использовать execute()
;отказ от его использования может (хотя я не знаю наверняка) привести к тому, что пул будет работать неоптимальным образом.Тем не менее, я не думаю, что использование offer()
будет прерывать исполнителя - похоже, что задачи удаляются из очереди с помощью следующего (также из ThreadPoolExecutor):
Runnable getTask() {
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take();
if (r != null)
return r;
if (workerCanExit()) {
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}
Этот getTask()
метод вызывается только из цикла, поэтому, если исполнитель не завершает работу, он блокируется до тех пор, пока в очередь не будет передано новое задание (независимо от того, откуда оно пришло).
Примечание : Несмотря на то, что я разместил здесь фрагменты кода из источника, мы не можем полагаться на них для окончательного ответа - мы должны только кодировать API.Мы не знаем, как реализация execute()
будет меняться со временем.