Executor 看起来像是一个干净的抽象。您什么时候想直接使用 Thread 而不是依赖更强大的执行器?
7 回答
为了提供一些历史,Executors 仅作为 Java 1.5 中的 java 标准的一部分添加。所以在某些方面 Executors 可以被看作是处理 Runnable 任务的一种新的更好的抽象。
有点过于简化了...... - 执行器是正确完成的线程,所以优先使用它们。
当我需要一些基于拉的消息处理时,我使用 Thread。例如,队列是在单独线程中的循环中的 take()-en。例如,您将队列包装在昂贵的上下文中 - 比如说 JDBC 连接、JMS 连接、要从单个磁盘处理的文件等。
在我被诅咒之前,你有什么情景吗?
编辑:
正如其他人所说,Executor
( ExecutorService
) 接口具有更大的潜力,因为您可以使用Executors
来选择一种行为:Java 5+ 中的调度、优先级、缓存等,或者 Java 1.4 的 juc 反向移植。
执行器框架可以防止崩溃的可运行文件并自动重新创建工作线程。在我看来,一个缺点是你必须在退出应用程序之前明确地shutdown()
和它们 - 这在 GUI 应用程序中并不容易。awaitTermination()
如果您使用有界队列,则需要指定 aRejectedExecutionHandler
否则新的可运行对象将被丢弃。
使用原始线程没有任何优势。您始终可以为 Executors 提供线程工厂,因此甚至可以选择自定义线程创建。
除非您需要在 Thread 本身中找不到的更具体的行为,否则不要使用 Thread。然后,您扩展 Thread 并添加您特别想要的行为。
否则只需使用 Runnable 或 Executor。
java.util.concurrent 包提供执行器接口,可用于创建线程。
Executor 接口提供了一个单一的方法,execute,旨在替代常见的线程创建习惯用法。如果 r 是 Runnable 对象,并且 e 是 Executor 对象,您可以替换
(新线程(r)).start();
和
e.执行(r);
参考这里
好吧,我认为 ThreadPoolExecutor 提供了更好的性能,因为它可以管理线程池,最大限度地减少实例化新线程的开销,分配内存......
如果您要启动数千个线程,它会为您提供一些您必须自己编程的排队功能......
线程和执行器是不同的工具,用于不同的场景......在我看来,就像在问为什么我可以使用 HashMap 时使用 ArrayList?它们不一样...
即使是单线程,也最好选择Executor,如下所示Thread
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
您可以在以下情况下使用Thread
overExecutor
您的应用程序需要有限的线程并且业务逻辑很简单
如果简单的多线程模型在没有线程池的情况下满足您的要求
您有信心在以下领域借助低级 API 管理线程生命周期 + 异常处理场景:
Inter thread communication, Exception handling, reincarnation of threads
由于意外错误
最后一点
如果您的应用程序不需要自定义
ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
在所有其他情况下,您可以选择ThreadPoolExecutor