tl;博士
- 是的,这两种方法实现了相同的目的:一些代码在后台线程上执行。
- 使用第二个(Executors 框架)而不是显式的
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 框架(参见 Tutorial by Oracle)的发明是为了让大多数程序员在大多数情况下不必掌握管理线程的艺术。因此,您不再需要自己实例化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 constructor Javadoc 使用 target,正如我在 run 方法中的评论中复制粘贴的那样。然而,我选择使用名为runnable 的变量。您可以选择 exportQuarterlySalesDataRunnable、task、target 或 pinkElephant 之类的名称。
终止线程
请注意,最终您需要终止线程。在您的应用程序运行期间,您可能不再需要线程或其当前正在执行的工作。或者您的应用可能正在结束其运行,在这种情况下,您必须关闭您的线程,否则在您的应用停止后它们会继续像僵尸一样运行。
执行器服务通过几个shutdown… 方法使线程终止变得容易。您可以选择中断任何当前正在完成的工作,或等到任何当前工作完成。
Lambda 语法
为了完整起见,我将提到您可以通过添加到现代 Java 中的 lambda 功能使用更短的语法。
必读提示:阅读、再阅读、再阅读 Brian Goetz 等人的精彩书籍 Java Concurrency in Practice。