tl; dr
- Да, два подхода достигли sh одного и того же конца: некоторый код выполняется в фоновом потоке.
- Используйте второй ( Executors framework), а не явное создание
Thread
. - Не зацикливайтесь на имени переменной, содержащей ссылку на ваш объект
Runnable
.
Подробности
Да, учитывая Runnable
(объект с методом run
), например:
public class ReportRunnable implements Runnable {
public void run() {
System.out.println( "Reporting at " + Instant.now() ); // Passing: ( Runnable target , String name ).
}
}
… затем делаем следующее:
Runnable runnable = new ReportRunnable() ;
thread = new Thread( runnable , "thread-process" );
thread.start();
… фактически то же самое, что и следующее:
ExecutorService executorService = Executors.newSingleThreadExecutor() ;
… // You should be keeping a reference to the executor service, so that you can later shut it down gracefully.
Runnable runnable = new ReportRunnable() ;
executorService.submit( runnable ) ;
В обоих случаях вы немедленно запускаете некоторую работу, выполняемую в фоновом потоке. В этом смысле они имеют одинаковый эффект. Но есть и важные различия.
Поймите, что структура Executors (см. Учебник от Oracle) была изобретена, чтобы облегчить большинство программистов в большинстве случаев ios от необходимости овладеть тонким искусством управления потоками. Таким образом, вам редко нужно создавать экземпляр Thread
самостоятельно. По возможности используйте среду исполнителя.
Одно отличие состоит в том, что метод submit
службы исполнителя возвращает объект Future
. В нашем коде выше мы игнорируем этот возвращенный объект. Но вы можете захотеть зафиксировать ссылку на этот объект, чтобы позже проконсультироваться о ходе выполнения или статусе завершения задачи.
Другое отличие состоит в том, что вы можете выбрать автоматический переход с одного потока на использование пула потоков управляется службой исполнителя. Бывают ситуации, когда вы можете захотеть, чтобы все группы задач совместно использовали один и тот же пул потоков. Услуга исполнителя делает это довольно просто.
ExecutorService executorService = Executors.newFixedThreadPool( 3 )
;
Большая разница в том, что вы можете использовать различные виды услуг исполнителя, предлагающих различные функции. Вы можете запланировать запуск задачи по истечении определенного времени, а не запускать немедленно. И вы можете запускать задачу несколько раз, например, отправлять электронное письмо с отчетом о состоянии каждый час.
ScheduledExecutorService ses = newSingleThreadScheduledExecutor() ;
… // You should be keeping a reference to the executor service, so that you can later shut it down gracefully.
Runnable runnable = new ReportRunnable() ;
ScheduledFuture<?> reportFuture = scheduler.scheduleAtFixedRate( runnable , 0 , 2 , TimeUnit.HOURS ) ;
Еще одним отличием является управление завершением потока, которое обсуждается ниже.
Имена переменных не имеют значения
Вы сказали:
Но Метод submit принимает задачу Runnable, а не цель Runnable
Кажется, вы зациклились на именовании переменных. Имена переменных здесь не важны. . Конструктор Thread
Javado c использует target
, как видно из моего комментария в моем методе run
. Тем не менее, я выбрал go с переменной с именем runnable
. Вы можете выбрать имя, например exportQuarterlySalesDataRunnable
, task
, target
или pinkElephant
.
Завершение потоков
Имейте в виду, что в конечном итоге вам нужно завершить поток (-ы). Во время выполнения вашего приложения вам может больше не понадобиться поток или выполняемая в настоящее время работа. Или ваше приложение может завершать свое выполнение, и в этом случае вы должны закрыть свои потоки или рискнуть, что они продолжат запускать zomb ie-like после остановки вашего приложения.
Служба исполнителя упрощает завершение потока, парой методов shutdown…
. Вы можете прервать любую текущую работу или дождаться ее завершения.
Лямбда-синтаксис
Для полноты я упомяну, что вы можете использовать более короткий синтаксис с помощью функций лямбда, добавленных в современные Java.
Обязательный совет : Прочтите, перечитайте и еще раз прочитайте превосходную книгу Java Параллелизм на практике Брайана Гетца и др.