56

Executor 看起来像是一个干净的抽象。您什么时候想直接使用 Thread 而不是依赖更强大的执行器?

4

7 回答 7

33

为了提供一些历史,Executors 仅作为 Java 1.5 中的 java 标准的一部分添加。所以在某些方面 Executors 可以被看作是处理 Runnable 任务的一种新的更好的抽象。

有点过于简化了...... - 执行器是正确完成的线程,所以优先使用它们。

于 2009-07-07T21:48:13.903 回答
8

当我需要一些基于拉的消息处理时,我使用 Thread。例如,队列是在单独线程中的循环中的 take()-en。例如,您将队列包装在昂贵的上下文中 - 比如说 JDBC 连接、JMS 连接、要从单个磁盘处理的文件等。

在我被诅咒之前,你有什么情景吗?

编辑

正如其他人所说,Executor( ExecutorService) 接口具有更大的潜力,因为您可以使用Executors来选择一种行为:Java 5+ 中的调度、优先级、缓存等,或者 Java 1.4 的 juc 反向移植。

执行器框架可以防止崩溃的可运行文件并自动重新创建工作线程。在我看来,一个缺点是你必须在退出应用程序之前明确地shutdown()和它们 - 这在 GUI 应用程序中并不容易。awaitTermination()如果您使用有界队列,则需要指定 aRejectedExecutionHandler否则新的可运行对象将被丢弃。

你可以看看Brian Goetz 等人:Java Concurrency in Practice (2006)

于 2009-07-07T21:10:15.370 回答
6

使用原始线程没有任何优势。您始终可以为 Executors 提供线程工厂,因此甚至可以选择自定义线程创建。

于 2009-07-07T21:08:35.280 回答
3

除非您需要在 Thread 本身中找不到的更具体的行为,否则不要使用 Thread。然后,您扩展 Thread 并添加您特别想要的行为。

否则只需使用 Runnable 或 Executor。

于 2009-07-07T21:14:40.633 回答
3

java.util.concurrent 包提供执行器接口,可用于创建线程。

Executor 接口提供了一个单一的方法,execute,旨在替代常见的线程创建习惯用法。如果 r 是 Runnable 对象,并且 e 是 Executor 对象,您可以替换

(新线程(r)).start();

e.执行(r);

参考这里

于 2012-12-24T19:45:46.210 回答
3

好吧,我认为 ThreadPoolExecutor 提供了更好的性能,因为它可以管理线程池,最大限度地减少实例化新线程的开销,分配内存......

如果您要启动数千个线程,它会为您提供一些您必须自己编程的排队功能......

线程和执行器是不同的工具,用于不同的场景......在我看来,就像在问为什么我可以使用 HashMap 时使用 ArrayList?它们不一样...

于 2010-09-28T15:49:33.753 回答
2

即使是单线程,也最好选择Executor,如下所示Thread

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);

您可以在以下情况下使用ThreadoverExecutor

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

  2. 如果简单的多线程模型在没有线程池的情况下满足您的要求

  3. 您有信心在以下领域借助低级 API 管理线程生命周期 + 异常处理场景:Inter thread communication, Exception handling, reincarnation of threads由于意外错误

最后一点

  1. 如果您的应用程序不需要自定义ThreadPoolExecutor

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

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

于 2015-12-19T17:10:42.980 回答