Разница между Executors.newFixedThreadPool(1) и Executors.newSingleThreadExecutor()
Мой вопрос: имеет ли смысл использовать Executors.newFixedThreadPool(1)??
, В двухпоточных (main + oneAnotherThread) сценариях эффективно ли использовать службу executor?. Создает новый поток напрямую, вызывая new Runnable(){ }
лучше, чем использовать ExecutorService? Каковы положительные и отрицательные стороны использования ExecutorService для таких сценариев?
PS: Основной поток и oneAnotherThread не имеют доступа к каким-либо общим ресурсам.
Я прошел через: Каковы преимущества использования ExecutorService?, и только одна нить за раз!
4 ответа
имеет ли смысл использовать
Executors.newFixedThreadPool(1)
?
Это по сути то же самое, что и Executors.newSingleThreadExecutor()
за исключением того, что последний не реконфигурируем, как указано в Javadoc, тогда как первый, если вы приведете его к ThreadPoolExecutor
,
В двухпоточных (main + oneAnotherThread) сценариях эффективно ли использовать службу executor?
Служба executor - это очень тонкая оболочка вокруг Thread, которая значительно облегчает управление жизненным циклом потока. Если единственное, что вам нужно, это new Thread(runnable).start();
и двигаться дальше, тогда нет реальной необходимости в ExecutorService.
В любых наиболее реальных случаях возможна возможность мониторинга жизненного цикла задач (через возвращенные Future
s) тот факт, что исполнитель будет воссоздавать потоки по мере необходимости в случае неперехваченных исключений, выигрыша в производительности при переработке потоков по сравнению с созданием новых и т. д., делает службу исполнителя гораздо более мощным решением при небольших дополнительных затратах.
Итог: я не вижу никаких минусов в использовании службы исполнителя по сравнению с потоком.
Разница между Executors.newSingleThreadExecutor(). Execute(команда) и новым потоком (команда).start (); проходит через небольшие различия в поведении между двумя вариантами.
Иногда нужно использовать Executors.newFixedThreadPool(1)
определить количество задач в очереди
private final ExecutorService executor = Executors.newFixedThreadPool(1);
public int getTaskInQueueCount() {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor;
return threadPoolExecutor.getQueue().size();
}
имеет ли смысл использовать Executors.newFixedThreadPool(1)??
Да. Это имеет смысл, если вы хотите обработать все представленные задания в порядке поступления
В двухпоточных (main + oneAnotherThread) сценариях эффективно ли использовать службу executor? Является ли создание нового потока напрямую путем вызова new Runnable(){ } лучше, чем использование ExecutorService?.
я предпочитаю ExecutorService
или же ThreadPoolExecutor
даже за 1 нитку.
См. Ниже вопрос SE для объяснения преимуществ ThreadPoolExecutor
над новым Runnable()
:
ExecutorService vs Casual Spawner
Каковы положительные и отрицательные стороны использования ExecutorService для таких сценариев?
Посмотрите на связанный вопрос SE относительно вариантов использования ExexutorService:
Java Fork/Join vs ExecutorService - когда использовать какой?
Относительно вашего запроса в строке темы (из grepcode) оба одинаковы:
newFixedThreadPool
API вернет ThreadPoolExecutor как ExecutorService:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
а также
newSingleThreadExecutor()
вернуть ThreadPoolExecutor как ExecutorService:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
Я согласен с ответом @assylias относительно сходства / различия.
Является ли создание нового потока напрямую путем вызова new Runnable(){ } лучше, чем использование ExecutorService?
Если вы хотите что-то вычислить для возвращаемого результата после компиляции потока, вы можете использовать интерфейс Callable, который можно использовать только с ExecutorService, но не с новым Runnable(){}. Метод submit() в ExecutorService, который принимает объект Callable в качестве аргумента, возвращает объект Future. В этом объекте Future вы проверяете, была ли задача завершена, если не используется метод isDone (). Также вы можете получить результаты, используя метод get (). В этом случае ExecutorService лучше, чем новый Runnable(){}.