SingleThreadExecutor VS 普通线程
SingleThreadExecutor VS plain thread
除了 Executor
接口相对于普通线程(例如管理)有一些优势之外,在执行以下操作之间是否存在任何真正的内部差异(性能差异大,资源消耗...):
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);
并且:
Thread thread = new Thread(runnable);
thread.start();
我在这里只问一个线程。
如果只得到一个Runnable
执行,那么没有太大区别。
使用普通线程可能会更有效一些,因为创建一个 ExecutorService
例如 ThreadPoolExecutor
除了创建一个新线程之外还有一些事情要做。比如创建阻塞队列,创建策略,虽然这些都是隐式完成的。
并且您必须 shutdown
执行此可运行程序后执行程序。否则这个池中的单线程永远不会退出。
它是一个抽象,那些总是出现在"cost":
- 一些(潜在的)数量 "performance penalty"
- 减少了 "control" 的数量(这就是重点 - 您不需要处理底层细节,所以,如果您不得不处理,...)
主要区别在于该服务允许您提交 多个 任务,而线程可以 运行 恰好一个 Runnable。另一方面,您必须担心诸如 "shutting down" 服务之类的事情。
一条经验法则:性能方面应该接近 "ignorable" 这里。因此,您更喜欢 "more abstract" 执行程序服务解决方案。因为这允许您将关注点与实际线程分开。更重要的是:如果您选择为该服务使用 不同的 类型的实现……您的其余代码不需要关心它。
长话短说:抽象成本,但在这种情况下,您通常更喜欢 "more abstract" 解决方案。因为最终,这会降低解决方案的复杂性。
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 }
documentation of ThreadPoolExecutor解释了它在什么情况下会带来优势:
Thread pools address two different problems: they usually provide
improved performance when executing large numbers of asynchronous
tasks, due to reduced per-task invocation overhead, and they provide a
means of bounding and managing the resources, including threads,
consumed when executing a collection of tasks. Each ThreadPoolExecutor
also maintains some basic statistics, such as the number of completed
tasks.
如果你只需要偶尔 运行 单线程一次(比如每小时一次),那么就性能而言,使用 ThreadPoolExecutor
可能会更慢,因为你需要实例化整个机器(池+线程),然后将其从内存中丢弃。
但是如果您想经常使用这个单线程(比如每 15 秒一次),那么优点是您只创建池和线程一次,将其保存在内存中, 并一直使用它来节省时间,不时创建一个新线程(这可能非常昂贵,如果你想每 15 秒左右使用一次)。
主要区别在于任务执行策略。
通过创建 Thread
实例或子类化 Thread
,您基本上是在执行单个任务。
另一方面,使用 Executors.newSingleThreadExecutor()
允许您提交多个任务。由于这些任务保证不会并发执行,因此您可以利用以下线程限制好处:
- 访问非线程安全的对象时不需要同步
- 一个任务的记忆效果保证对下一个任务可见
除了 Executor
接口相对于普通线程(例如管理)有一些优势之外,在执行以下操作之间是否存在任何真正的内部差异(性能差异大,资源消耗...):
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);
并且:
Thread thread = new Thread(runnable);
thread.start();
我在这里只问一个线程。
如果只得到一个Runnable
执行,那么没有太大区别。
使用普通线程可能会更有效一些,因为创建一个 ExecutorService
例如 ThreadPoolExecutor
除了创建一个新线程之外还有一些事情要做。比如创建阻塞队列,创建策略,虽然这些都是隐式完成的。
并且您必须 shutdown
执行此可运行程序后执行程序。否则这个池中的单线程永远不会退出。
它是一个抽象,那些总是出现在"cost":
- 一些(潜在的)数量 "performance penalty"
- 减少了 "control" 的数量(这就是重点 - 您不需要处理底层细节,所以,如果您不得不处理,...)
主要区别在于该服务允许您提交 多个 任务,而线程可以 运行 恰好一个 Runnable。另一方面,您必须担心诸如 "shutting down" 服务之类的事情。
一条经验法则:性能方面应该接近 "ignorable" 这里。因此,您更喜欢 "more abstract" 执行程序服务解决方案。因为这允许您将关注点与实际线程分开。更重要的是:如果您选择为该服务使用 不同的 类型的实现……您的其余代码不需要关心它。
长话短说:抽象成本,但在这种情况下,您通常更喜欢 "more abstract" 解决方案。因为最终,这会降低解决方案的复杂性。
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 }
documentation of ThreadPoolExecutor解释了它在什么情况下会带来优势:
Thread pools address two different problems: they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks. Each ThreadPoolExecutor also maintains some basic statistics, such as the number of completed tasks.
如果你只需要偶尔 运行 单线程一次(比如每小时一次),那么就性能而言,使用 ThreadPoolExecutor
可能会更慢,因为你需要实例化整个机器(池+线程),然后将其从内存中丢弃。
但是如果您想经常使用这个单线程(比如每 15 秒一次),那么优点是您只创建池和线程一次,将其保存在内存中, 并一直使用它来节省时间,不时创建一个新线程(这可能非常昂贵,如果你想每 15 秒左右使用一次)。
主要区别在于任务执行策略。
通过创建 Thread
实例或子类化 Thread
,您基本上是在执行单个任务。
另一方面,使用 Executors.newSingleThreadExecutor()
允许您提交多个任务。由于这些任务保证不会并发执行,因此您可以利用以下线程限制好处:
- 访问非线程安全的对象时不需要同步
- 一个任务的记忆效果保证对下一个任务可见