首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ExecutorService SingleThreadExecutor

ExecutorService SingleThreadExecutor
EN

Stack Overflow用户
提问于 2016-03-31 08:49:46
回答 2查看 17.8K关注 0票数 4

我有一个对象列表,根据用户交互,一些对象需要异步工作。就像这样:

代码语言:javascript
复制
for(TheObject o : this.listOfObjects) {
   o.doWork();
}

TheObject实现了一个ExecutorService (SingleThread!),用于完成这项工作。TheObject类型的每个对象都实例化一个ExecutorService。我不想让千层面编码。同时,我没有足够的对象,无法在需要线程池的情况下生成额外的提取层。

我想引用关于CachedThreadPools的Java文档。

没有使用60秒的线程被终止并从缓存中删除。因此,一个空闲足够长的池将不会消耗任何资源。。

第一个问题:对于SingleThreadExecutor来说也是这样吗?线程终止了吗?JavaDoc没有提到SingleThreadExecutor。在这个应用程序中,这一点也不重要,因为我一方面有大量的对象可以依赖。只是好奇。

此外,doWork()方法的TheObject需要调用ExecutorService#.submit()方法来完成工作异步。隐式调用doWork()方法(我敢打赌)是可能的吗?这是设计异步方法的可行方法吗?

代码语言:javascript
复制
void doWork() {
   if(!isRunningAsync) {
      myExecutor.submit(doWork());
   } else {
      // Do Work...
   }
}
EN

回答 2

Stack Overflow用户

发布于 2016-03-31 09:15:12

第一个问题:对于SingleThreadExecutor来说也是这样吗?线程终止了吗?

看看Executors的源代码,比较一下newCachedThreadPoolnewSingleThreadExecutor的实现。

代码语言:javascript
复制
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.SECONDS0L, TimeUnit.MILLISECONDS

有效地(但实际上并不是),这些参数被传递给ThreadPoolExecutor.setKeepAliveTime。查看该方法的Javadoc:

时间值为零将导致多余线程在执行任务后立即终止。

其中“超额线程”实际上指的是“超出核心池大小的线程”。

  • 缓存的线程池是用零核心线程和(实际上)无限数量的非核心线程创建的;因此,任何线程都可以在保持活动时间之后终止。
  • 单线程执行器是用一个核心线程和零个非核心线程创建的;因此,在保持活动时间之后,没有可以终止的线程:它的一个核心线程一直处于活动状态,直到关闭整个ThreadPoolExecutor

(感谢@GPI指出我之前的解释是错误的)。

票数 8
EN

Stack Overflow用户

发布于 2016-03-31 10:46:45

第一个问题:

没有使用60秒的线程将被终止并从缓存中删除。因此,长时间空闲的池不会消耗任何资源。 对SingleThreadExecutor?也是这样吗?

SingleThreadExecutor的工作方式不同。由于在创建过程中配置的值,它没有超时概念。

SingleThread的终止是可能的。但是它保证始终存在一个线程来处理任务队列中的任务。

来自newSingleThreadExecutor文档:

代码语言:javascript
复制
public static ExecutorService newSingleThreadExecutor()

创建一个执行器,该执行器使用单个工作线程对无限制队列进行操作。(但是请注意,如果这个单个线程由于关闭前执行期间的失败而终止,那么如果需要执行后续任务,将有一个新线程代替它。)

任务保证按顺序执行,在任何给定时间都不会有多个任务处于活动状态。与其他等价的newFixedThreadPool(1)不同,返回的执行器保证不会被重新配置为使用其他线程。

第二个问题:

此外,doWork()方法的TheObject需要调用ExecutorService#.submit()方法来完成工作异步

代码语言:javascript
复制
for(TheObject o : this.listOfObjects) {
   o.doWork();
}

可以更改为

代码语言:javascript
复制
ExecutorService executorService = Executors.newSingleThreadExecutor();

executorService.execute(new Runnable() {
    public void run() {
        System.out.println("Asynchronous task");
    }
});

executorService.shutdown();

使用CallableRunnable接口,并在run()方法或call()方法中添加doWork()代码。该任务将同时执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36328492

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档