单线程执行器 VS 平线程

2022-09-01 03:56:57

除了接口比纯线程(例如管理)具有一些优势之外,在以下操作之间是否存在任何真正的内部差异(巨大的性能差异,资源消耗...):Executor

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);

和:

Thread thread = new Thread(runnable);
thread.start();

我在这里只问一个线程。


答案 1

Executors#newSingleThreadExecutor() 在引擎盖下创建 ThreadPoolExecutor 对象,
请参阅此处的代码:http://www.docjar.com/html/api/java/util/concurrent/Executors.java.html

  133       public static ExecutorService newSingleThreadExecutor() {
  134           return new FinalizableDelegatedExecutorService
  135               (new ThreadPoolExecutor(1, 1,
  136                                       0L, TimeUnit.MILLISECONDS,
  137                                       new LinkedBlockingQueue<Runnable>()));
  138       }

ThreadPoolExecutor的文档解释了它在哪些情况下具有优势:

线程池解决了两个不同的问题:由于减少了每个任务的调用开销,它们通常在执行大量异步任务时提供改进的性能,并且它们提供了一种限制和管理在执行一组任务时使用的资源(包括线程)的方法。每个 ThreadPoolExecutor 还维护一些基本的统计信息,例如已完成任务的数量。

如果您只需要偶尔运行一次单个线程(例如每小时一次),那么就性能而言,使用可能会更慢,因为您需要实例化整个机器(池+线程),然后将其从内存中丢弃。ThreadPoolExecutor

但是,如果您想经常使用这个单个线程(例如每15秒一次),那么优点是您只创建一次池和线程,将其保存在内存中,并一直使用它,从而节省时间,不时地创建新线程(如果要使用它,可能会非常昂贵,请说每15秒左右)。


答案 2

主要区别在于任务执行策略。

通过创建实例或子类化,您基本上执行单个任务。ThreadThread

另一方面,使用允许您提交多个任务。由于这些任务保证不会并发执行,因此这允许您利用以下线程限制优势:Executors.newSingleThreadExecutor()

  • 访问非线程安全对象时无需同步
  • 一个任务的记忆效果保证对下一个任务可见