这里应该优先选择线程(Thread)还是执行器(Executor)?

6
据我理解,执行器有助于处理可运行对象的执行。例如,当我有多个工作线程并完成它们的任务后就会终止时,我会选择使用执行器。执行器将处理创建和终止所需的线程来执行工作的可运行对象。
然而现在我面临另一种情况。固定数量的类/对象应该封装自己的线程。因此,在创建这些对象时启动线程,并且该线程将在这些对象的整个生命周期内持续运行。这些少数对象反过来在程序开始时创建,并存在于整个运行时间中。
我想在这种情况下,线程比执行器更可取,但是当我阅读互联网时,似乎每个人都建议在任何可能的情况下都使用执行器而不是线程。
请问有人能告诉我我应该在这里选择执行器还是线程以及为什么吗?
谢谢

这些线程在它们的生命周期内会做什么?它们会100%忙于计算圆周率的小数,还是会闲置直到与之交互? - aioobe
这取决于...其中一些将有大约50%的空闲时间,而其他一些则只有大约10%。 - flxh
另外一些将会100%忙于计算树的哈希值。 - flxh
3个回答

3
你有些混淆了。 Executor 只是一个接口。 Thread 是一个核心类。没有任何直接暗示 Executor 实现在单独的线程中执行任务的东西。
请读一下 JavaDoc 的前几行。 Executor 因此,如果您想要完全控制,请使用 Thread 并自己处理事情。

他可能在思考ExecutorServices和Executors,例如ThreadPoolExecutor。 - aioobe
@aioobe 是的,我知道。但那只是一种思考方式。 - peter.petrov
抱歉造成困惑。但是,正如aioobe所说,我指的是ExecutorServices。 - flxh

1

如果没有更多上下文信息,很难给出一个好的答案,但一般而言,需要使用Thread的情况相当少。如果你开始尝试手动使用synchronized来同步程序,我敢打赌事情很快就会失控。(更不用说调试代码有多难了。)

我上次使用线程是想在后台记录一些音频。这是一种“启动”/“停止”的方式,而不是“任务导向”的方式。(我曾经努力寻找一个可以为我封装它的音频库,但失败了。)

如果您选择使用线程解决方案,建议您尝试将线程的范围限制在相关对象内部执行。这将尽可能避免强制您考虑整个代码中的发生顺序、线程安全发布值等。


Java内存模型非常复杂,如果从happens before关系的角度思考,很容易失控。在几乎所有情况下,您应该尝试使用java.util.concurrent提供的类,在更高的抽象级别上工作。 - aioobe
目前我正在使用 synchronized 手动同步我的程序,你有什么其他的替代方案吗? - flxh
2
@user3187049 我个人认为,继续使用它,并先学习低级别的东西。这样你会更加熟悉高级别的东西。 :) - peter.petrov
1
简而言之,你要么使用 Thread,因为你正在实现自定义 Executor Service;或者使用现有的实现。很少情况需要自定义实现。 - Marko Topolnik
1
也许您应该描述您真正需要的东西,因为我有一种感觉,您正在为解决问题创建错误的解决方案。 - Gaskoin
显示剩余5条评论

1
  • ExecutorService可以拥有线程池

它可以优化性能,因为创建一个Thread是昂贵的。

  • ExecutorService具有生命周期控制

提供了shutdown()shutdownNow()等方法。

  • ExecutorService很灵活

您可以调用多种行为:自定义ThreadFactory、设置线程池大小、延迟行为ScheduledThreadPoolExecutor等...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接