什么时候应该使用Java的Thread而不是Executor?

58

Executor看起来像是一个干净的抽象层。但什么情况下您会想要直接使用Thread,而不是依赖更健壮的executor呢?

7个回答

35

从历史上看,执行器(Executors)仅在Java 1.5中作为Java标准的一部分添加。因此,在某些方面,可以将执行器视为处理可运行任务的新型更好抽象。

有点过于简化了... - 执行器是正确使用线程的方式,因此请优先使用它们。


10
好的,Erlang 是正确实现线程的语言,但在 Java 中 Executors 已经达到了最好的水平。 - skaffman

8
当我需要基于拉取的消息处理时,我使用线程。例如,在单独的线程中循环获取队列的take()方法。例如,你在昂贵的上下文中包装一个队列 - 比如一个JDBC连接、JMS连接、要从单个磁盘处理的文件等。
在我发誓前,你有某些场景吗?
编辑:
正如其他人所述,Executor(ExecutorService)接口具有更高的潜力,因为您可以使用Java 5+中的Executors选择行为:定时,优先级,缓存等,或者针对Java 1.4的j.u.c回退版本。
执行程序框架具有保护崩溃的可运行对象并自动重新创建工作线程的功能。我认为一个缺点是,您必须在退出应用程序之前明确关闭()和awaitTermination()它们 - 这在GUI应用程序中并不容易。
如果您使用有界队列,则需要指定RejectedExecutionHandler或新的可运行项将被丢弃。
您可以查看Brian Goetz等人的“Java Concurrency in Practice(2006)” Brian Goetz et al: Java Concurrency in Practice (2006)

我正在使用线程实现轮询队列,但是当我注意到可以更容易地使用Executor(更容易检测完成时)获得完全相同的功能时。 - ripper234

5

使用原始线程没有任何优势。您可以始终向执行程序提供一个线程工厂,因此即使是自定义线程创建选项也已经涵盖。


3

java.util.concurrent包提供了Executor接口,可用于创建线程。

Executor接口提供了一个单独的方法execute,旨在成为常见的线程创建构造的替代品。如果r是Runnable对象,e是Executor对象,您可以将

(new Thread(r)).start();

替换为

e.execute(r);

参考此处


文档没有说明在执行“e.execute(r)”时是否需要shutdown()。有人知道吗? - Zorb

3

除非你需要Thread本身没有的更具体的行为,否则不要使用Thread。然后扩展Thread并添加你想要的特定行为。

否则,只需使用Runnable或Executor。


2
您可以随时从ThreadFactory返回自定义的Thread对象,并将其传递给Executor。 - skaffman

3
我认为 ThreadPoolExecutor 提供了更好的性能,因为它管理线程池,减少了实例化新线程和分配内存的开销...
如果你要启动数千个线程,它提供了一些队列功能,否则你需要自己编写...
线程和 Executors 是不同的工具,用于不同的场景... 我的看法是,这就像问我为什么要使用 ArrayList,而不是 HashMap?它们是不同的...

1

即使只有单个线程,也最好使用Executor而不是Thread

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);

以下情况下,您可以在Executor之上使用Thread

  1. 您的应用程序需要有限的线程,并且业务逻辑很简单

  2. 如果简单的多线程模型满足您的需求而不需要线程池

  3. 您有信心通过低级API在以下领域管理线程的生命周期+异常处理场景:线程间通信、异常处理、线程的重启由于意外错误

最后一点

  1. If your application does not need customization of various features of ThreadPoolExecutor

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

在其他所有情况下,您可以选择使用 ThreadPoolExecutor


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接