当前位置:  开发笔记 > 编程语言 > 正文

为什么ExecutorCompletionService不使用ExecutorService池中的线程

如何解决《为什么ExecutorCompletionService不使用ExecutorService池中的线程》经验,为你挑选了1个好方法。

由于某种原因,java.util.concurrent.ExecutorCompletionService它不使用java.util.concurrent.ExecutorService线程池中的线程.这会影响ExecutorCompletionService.submit()方法调用的"阻塞"执行.请考虑以下代码:

package completionservicedemo1;

import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class CompletionServiceDemo1 {

    static final ExecutorService executor = Executors.newFixedThreadPool(10, new ThreadFactory() {

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName("Executor-Thread");
            try {
                System.out.println("Thread going to sleep: "+Thread.currentThread().getName());
                thread.sleep(5000L);
                System.out.println("Thread awakened: "+Thread.currentThread().getName());
            } catch (InterruptedException ex) {
                System.out.println("InteruptedException: "+ex);
            }
            return thread;
        }
    });

    static final ExecutorCompletionService completionService = new ExecutorCompletionService<>(executor);
    static byte val=1;

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("App start time: "+ new Date());

        completionService.submit(()->"String"+ ++val);
        System.out.println("All tasks submitted at: "+ new Date());

    }    
}

并输出:

应用开始时间:2016年1月5日星期二00:20:27

线程进入睡眠状态:主要

线程被唤醒:主要

所有任务在2016年1月5日星期二00:20:32提交

很明显,ExecutorCompletionStage没有使用来自ExecutorService池的线程,因为这completionService.submit(()->"String"+ ++val);会在延迟5秒后响应.

理想情况下,submit()方法应将传递的Callable实例任务提交到ExecutorService池以进行并发执行.但这显然不会发生,因为输出中的线程名称显示.

有人可以解释一下这里发生的事情吗?为什么不同时在ExecutorService线程池上计算Callable?为什么completionService.submit()阻塞(5s)?



1> Sotirios Del..:

为什么不ExecutorCompletionService使用ExecutorService池中的线程?

确实如此.见答案结束.

该的javadoc的newFixedThreadPool状态

使用提供的ThreadFactory方法在需要时创建新线程

换句话说,返回ExecutorService的线程是newThread按需延迟创建的.

提交任务时

completionService.submit(()->"String"+ ++val);

没有Thread可用于接受任务的实例.因此ExecutorService将使用创建一个新线程newThread.它在调用线程中执行此操作main.由于你newThread的实现是睡5秒,这正是它的作用.一旦sleep完成,newThread将返回Thread实例,该实例ExecutorService将启动并执行提交

()->"String"+ ++val

请注意,您的任务仅连接a Stringint值并返回结果.

将其更改为

Future future = completionService.submit(() -> "String" + ++val + " Thread " + Thread.currentThread());
System.out.println("All tasks submitted at: " + new Date());
System.out.println("Future returned: " + future.get());

调用get返回Future来等待它完成并看到有用的东西.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有