java ExecutorService SingleThreadExecutor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36328492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ExecutorService SingleThreadExecutor
提问by El Mac
I have a list of objects, from which depending on user interaction some objects need to do work asynchronically. Something like this:
我有一个对象列表,根据用户交互,其中一些对象需要异步工作。像这样的东西:
for(TheObject o : this.listOfObjects) {
o.doWork();
}
The class TheObject
implements an ExecutorService
(SingleThread!), which is used to do the work. Every object of type TheObject instantiates an ExecutorService
. I don't want to make lasagna code. I don't have enough Objects at the same time, to make an extra extraction layer with thread pooling needed.
该类TheObject
实现了一个ExecutorService
(SingleThread!),用于完成工作。TheObject 类型的每个对象都会实例化一个ExecutorService
. 我不想制作千层面代码。我没有足够的对象同时创建一个额外的提取层,需要线程池。
I want to cite the Java Documentation about CachedThreadPools:
我想引用关于CachedThreadPools的 Java 文档:
Threads that have not been used for sixty seconds are terminated and removed from the cache.Thus, a pool that remains idle for long enough will not consume any resources.
60 秒内未使用的线程将被终止并从缓存中删除。因此,保持空闲足够长时间的池 不会消耗任何资源。
First question:Is this also true for a SingleThreadExecutor? Does the thread get terminated? JavaDoc doesn't say anything about SingleThreadExecutor. It wouldn't even matter in this application, as I have an amount of objects I can count on one hand. Just curiosity.
第一个问题:对于 SingleThreadExecutor 也是如此吗?线程是否终止?JavaDoc 没有提及 SingleThreadExecutor。在这个应用程序中这甚至无关紧要,因为我有很多可以单手数的对象。好奇而已。
Furthermore the doWork()
method of TheObject
needs to call the ExecutorService#.submit()
method to do the work async. Is it possible (I bet it is) to call the doWork()
method implicitly? Is this a viable way of designing an async method?
此外,该doWork()
方法TheObject
需要调用该ExecutorService#.submit()
方法来异步执行工作。是否有可能(我敢打赌)doWork()
隐式调用该方法?这是设计异步方法的可行方法吗?
void doWork() {
if(!isRunningAsync) {
myExecutor.submit(doWork());
} else {
// Do Work...
}
}
回答by Andy Turner
First question: Is this also true for a SingleThreadExecutor? Does the thread get terminated?
第一个问题:对于 SingleThreadExecutor 也是如此吗?线程是否终止?
Take a look at the source code of Executors
, comparing the implementations of newCachedThreadPool
and newSingleThreadExecutor
:
看看源代码Executors
,比较的实现newCachedThreadPool
和newSingleThreadExecutor
:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
The primary difference (of interest here) is the 60L, TimeUnit.SECONDS
and 0L, TimeUnit.MILLISECONDS
.
主要区别(此处有趣)是60L, TimeUnit.SECONDS
和0L, TimeUnit.MILLISECONDS
。
Effectively (but not actually), these parameters are passed to ThreadPoolExecutor.setKeepAliveTime
. Looking at the Javadoc of that method:
有效地(但实际上并非),这些参数被传递到ThreadPoolExecutor.setKeepAliveTime
. 查看该方法的Javadoc:
A time value of zero will cause excess threads to terminate immediately after executing tasks.
时间值为零将导致多余的线程在执行任务后立即终止。
where "excess threads" actually refers to "threads in excess of the core pool size".
其中“多余线程”实际上是指“超过核心池大小的线程”。
- The cached thread pool is created with zero core threads, and an (effectively) unlimited number of non-core threads; as such, any of its threads can be terminated after the keep alive time.
- The single thread executor is created with 1 core thread and zero non-core threads; as such, there are no threads which can be terminated after the keep alive time: its one core thread remains active until you shut down the entire
ThreadPoolExecutor
.
- 缓存线程池由零核心线程和(实际上)无限数量的非核心线程创建;因此,它的任何线程都可以在保持活动时间后终止。
- 单线程执行器由 1 个核心线程和 0 个非核心线程创建;因此,在保持活动时间之后没有可以终止的线程:它的一个核心线程保持活动状态,直到您关闭整个
ThreadPoolExecutor
.
(Thanks to @GPI for pointing out that I was wrong in my interpretation before).
(感谢@GPI 指出我之前的解释是错误的)。
回答by Ravindra babu
First question:
第一个问题:
Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources.
Is this also true for a SingleThreadExecutor?
60 秒内未使用的线程将被终止并从缓存中删除。因此,保持空闲足够长时间的池不会消耗任何资源。
对于 SingleThreadExecutor 也是如此吗?
SingleThreadExecutor
works differently. It don't have time-out concept due to the values configured during creation.
SingleThreadExecutor
工作方式不同。由于在创建期间配置的值,它没有超时概念。
Termination of SingleThread is possible. But it guarantees that always one Thread exists to handle tasks from task queue.
可以终止 SingleThread。但它保证始终存在一个线程来处理任务队列中的任务。
From newSingleThreadExecutordocumentation:
public static ExecutorService newSingleThreadExecutor()
Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
创建一个 Executor,它使用单个工作线程在无界队列中运行。(但是请注意,如果这个单线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,一个新线程将取而代之。)
Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
任务保证按顺序执行,并且在任何给定时间不会有超过一个任务处于活动状态。与其他等效的 newFixedThreadPool(1) 不同,返回的执行程序保证不可重新配置以使用其他线程。
Second question:
第二个问题:
Furthermore the doWork() method of TheObject needs to call the ExecutorService#.submit() method to do the work async
此外,TheObject 的 doWork() 方法需要调用 ExecutorService#.submit() 方法来异步执行工作
for(TheObject o : this.listOfObjects) {
o.doWork();
}
can be changed to
可以改为
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
public void run() {
System.out.println("Asynchronous task");
}
});
executorService.shutdown();
with Callable
or Runnable
interface and add your doWork
() code in run()
method or call()
method. The task will be executed concurrently.
withCallable
或Runnable
interface 并doWork
在run()
方法或call()
方法中添加您的() 代码。任务将并发执行。