【问题标题】:When should we use Java's Thread over Executor?我们什么时候应该使用 Java 的 Thread over Executor?
【发布时间】:2010-11-08 20:30:30
【问题描述】:

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

【问题讨论】:

    标签: java multithreading concurrency executor


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      编辑

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

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

      你可以看看Brian Goetz et al: Java Concurrency in Practice (2006)

      【讨论】:

      • 我正在使用线程实现轮询队列,当我注意到我可以获得完全相同的功能但使用 Executor 时更容易(更容易检测到何时完成)。
      【解决方案3】:

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

      否则只需使用 Runnable 或 Executor。

      【讨论】:

      • 您始终可以从 ThreadFactory 返回您的自定义 Thread 对象,并将其传递给 Executor。
      【解决方案4】:

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

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

      【讨论】:

      • 嗯,Erlang 的线程做得很好,但是执行器和 java 中的一样好......
      【解决方案5】:

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

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

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

      【讨论】:

        【解决方案6】:

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

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

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

        e.execute(r);

        参考here

        【讨论】:

        • 文档没有说明在“e.execute(r)”的情况下是否需要 shutdown()。有人知道吗?
        【解决方案7】:

        更喜欢Executor 而不是Thread 总是更好,即使是如下的单线程

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
        

        您可以在以下场景中使用Thread 而不是Executor

        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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-07
          • 2017-08-12
          • 1970-01-01
          • 2011-07-04
          • 2017-09-13
          • 2021-12-29
          • 2011-07-17
          • 2022-01-26
          相关资源
          最近更新 更多