Разница между Executors.newSingleThreadExecutor(). Execute(команда) и новым потоком (команда).start();

Ну, название говорит, что разница между Executors.newSingleThreadExecutor().execute(command) а также new Thread(command).start();

5 ответов

Решение

Поведенчески, почти ничего.

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

Одно заметное отличие, когда вы бежите new Thread(someRunnable).start(); когда закончится работа, нить тихо умрет.

Исполнитель, тем не менее, будет сохраняться до тех пор, пока вы не выключите его. Так работает Executors.newSingleThreadExecutor().execute(command) Когда вы думаете, что ваше приложение или JVM могут быть завершены, Исполнитель может все еще работать в фоновом потоке.

С Executor.execute, если Error или же RuntimeException брошен в Executor он будет проглочен молча, пока new Thread() распечатает его System.err,

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

public void sendEventSingleThreadExecutor(Event e){
  Executor.singleThreadExecutor().execute(()->{//send the event here})
}

Теперь, даже если вы звоните sendEventSingleThreadExecutor метод в 10 раз, он будет использовать только один поток для передачи их. Он не будет создавать каждый раз новый поток. Это означает, что события будут отправляться последовательно или синхронно! Вы можете прочитать больше здесь:

Теперь посмотрим на приведенный ниже пример с новой веткой.

public void sendEventThread(Event e){
  Thread(//send the event here).start();
}

Если вы вызовете его 10 раз, он создаст 10 новых потоков. Это означает, что выполнение будет асинхронным! И это может быть опасно, оно может создавать множество потоков в зависимости от того, сколько раз вы вызываете функции sendEventThread.

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

Дополнительная информация отсюда

newSingleThreadExecutor. Однопоточный исполнитель создает один рабочий поток для обработки задач, заменяя его, если он неожиданно умирает. Гарантируется, что задачи будут обрабатываться последовательно в соответствии с порядком, установленным очередью задач (FIFO, LIFO, порядок приоритета).[4]

[4] Однопоточные исполнители также обеспечивают достаточную внутреннюю синхронизацию, чтобы гарантировать, что любая запись в память, сделанная задачами, будет видна для последующих задач; это означает, что объекты могут быть безопасно ограничены "потоком задачи", даже если этот поток может время от времени заменяться другим.

Я предпочитаю использовать ExecutorService или же ThreadPoolExecutor даже для однозначных потоков. Они предлагают больше гибкости.

Посмотри на ExecutorService & ThreadPoolExecutor разделы в связанных вопросах SE:

Java Форк / Объединить пул, ExecutorService и CountDownLatch

Java Fork/Join vs ExecutorService - когда использовать какой?

Предположим, что вы начали с собственного потока вместо ExecutorService, В будущем, если потребуется поддержка нескольких потоков, ExecutorService или же ThreadPoolExecutor предложит вам лучший контроль и гибкость для вас. Вы можете точно настроить необходимое количество параметров в этих ниже API.

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)

Executors.newSingleThreadExecutor(). Execute (команда) будет повторно использовать ранее созданный поток, он не будет создавать новый поток, как в случае нового Thread (). Если поток, который не использовался в течение шестидесяти секунд, завершается, это своего рода пул, который содержит один поток, который создает свой эквивалент newFixedThreadPool(1).

Другие вопросы по тегам