我有一个对象列表,根据用户交互,一些对象需要异步工作.像这样的东西:
for(TheObject o : this.listOfObjects) {
o.doWork();
}
类TheObject实现了一个ExecutorService(SingleThread!),用于完成工作. TheObject类型的每个对象都实例化一个ExecutorService.我不想制作lasagna code.我没有足够的对象同时进行额外的提取层,需要使用线程池.
我想引用关于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.
第一个问题:SingleThreadExecutor也是如此吗?线程是否被终止? JavaDoc没有说任何关于SingleThreadExecutor的内容.在这个应用程序中它甚至都不重要,因为我有一些可以依靠的对象.好奇而已.
此外,TheObject的doWork()方法需要调用ExecutorService#.submit()方法来执行异步工作.是否可以(我敢打赌)隐式调用doWork()方法?这是设计异步方法的可行方法吗?
void doWork() {
if(!isRunningAsync) {
myExecutor.submit(doWork());
} else {
// Do Work...
}
}
解决方法:
First question: Is this also true for a SingleThreadExecutor? Does the thread get terminated?
看一下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>()));
}
主要区别(此处感兴趣)是60L,TimeUnit.SECONDS和0L,TimeUnit.MILLISECONDS.
实际上(but not actually),这些参数传递给ThreadPoolExecutor.setKeepAliveTime
.查看该方法的Javadoc:
A time value of zero will cause excess threads to terminate immediately after executing tasks.
其中“多余线程”实际上是指“超过核心池大小的线程”.
>使用零核心线程和(有效)无限数量的非核心线程创建缓存线程池;因此,任何线程都可以在保持活动时间之后终止.
>使用1个核心线程和零个非核心线程创建单线程执行程序;因此,在保持活动时间之后没有可以终止的线程:它的一个核心线程保持活动状态,直到你关闭整个ThreadPoolExecutor.
(感谢@GPI指出我之前的解释错了).