当前位置: 首页 > 知识库问答 >
问题:

单线程执行器与普通线程

田易安
2023-03-14

除了Executor接口比普通线程(例如管理)有一些优势之外,执行以下操作之间是否存在真正的内部差异(性能差异大、资源消耗……):

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

以及:

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

我只问这里的一个线索。

共有3个答案

公西飞鸾
2023-03-14

这是一个抽象概念,这些抽象概念总是以“成本”为代价:

  • 一些(潜在的)量的"业绩处罚"
  • 减少了“控制”的数量(这就是重点——你不需要处理低层次的细节,所以,如果你不得不这样做,...)

主要区别在于服务允许您提交多个任务,而线程只能运行一个可运行的任务。另一方面,您必须担心诸如“关闭”服务之类的事情。

经验法则:这里的性能方面应该接近“可忽略”。因此,您更喜欢“更抽象”的executor服务解决方案。因为这允许您将关注点与实际线程分离。更重要的是:如果您选择为该服务使用不同类型的实现。。。代码的其余部分不需要考虑这一点。

长话短说:抽象成本很高,但在这种情况下,您通常更喜欢“更抽象”的解决方案。因为最终,这降低了解决方案的复杂性。

暨正真
2023-03-14

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

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

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

  • 访问非线程安全的对象时不需要同步
  • 一项任务的记忆效果保证对下一项任务可见
戎洛华
2023-03-14

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可能会更慢,因为您需要实例化整个机器(池线程),然后将其从内存中丢弃。

但是如果你想经常使用这个线程(比如每15秒),那么好处是你只创建一次池和线程,把它保存在内存中,并且一直使用它,节省了每隔一段时间创建一个新线程的时间(如果你想每15秒左右使用一次,这可能会很贵)。

 类似资料:
  • 6.7.1.单线程执行 Android程序默认运行在单线程之下。单线程顺序执行所有的操作,这一操作完成之前,下一个操作绝不会执行。这一行为被称作“阻塞”(blocking)。 图6.8. 单线程执行 这个线程也被称作UI线程,意思是程序中用户界面的相关操作都在这里执行。除处理所有UI元素的渲染之外,事件的响应也由它负责。比如触摸屏幕、点击按钮等等。图6.8 "单线程执行"展示了在只有一个UI线程时

  • 本文向大家介绍谈谈Java中的守护线程与普通线程,包括了谈谈Java中的守护线程与普通线程的使用技巧和注意事项,需要的朋友参考一下 守护线程与普通线程的唯一区别是:当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则不会退出。(以上是针对正常退出,调用System.exit则必定会退出) 所以setDeamon(true)的唯一意义就是告诉JVM不需要等待它

  • 我正在使用线程池执行器更改遗留设计。详情如下:- 遗留:-对于遗留设计,在应用程序启动时创建600个线程。和放置在各种池中,然后在需要时提取这些池,并将任务分配给相应的线程。 新:-在新设计中,我将线程池替换为执行器服务 我观察到的是,对于Executor,在启动时不会创建线程。它们是在从客户端激发请求时创建的。因此,与前一个线程相比,在内存中创建的线程要少得多。 但我的问题是,这样做是否正确,因

  • 我确信这两个列表都不是空的,并且正在调用,但是没有调用order execution run方法....

  • 消费者是一个spring集成项目,它从消息队列中消费并执行大量处理。我使用Executor通道并行处理消息,然后流通过一些公共处理程序类。 请在下面的代码片段中找到- -我们从EMS队列接收消息并将其发送到路由器 -基于以下消息的id:“特定ExecutorChannel实例配置了一个单线程执行器。每个ExecutorChannel都将是它的专用执行器,只有一个线程。 -所有ExecutorCha

  • 我们正在对使用SpringBoot 2.2.2和Spring执行器的应用程序进行性能测试。 我们希望监控: 正在使用多少tomcat线程 有多少tomcat请求正在排队 正在使用多少个ThreadPoolTaskExector线程(我们将@Async与线程池一起用于某些任务) 执行器中是否提供此信息?我看不到需要使用哪些指标。