由于某种原因,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 ExecutorCompletionServicecompletionService = 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)?
为什么不
ExecutorCompletionService
使用ExecutorService
池中的线程?
确实如此.见答案结束.
该的javadoc的newFixedThreadPool
状态
使用提供的
ThreadFactory
方法在需要时创建新线程
换句话说,返回ExecutorService
的线程是newThread
按需延迟创建的.
提交任务时
completionService.submit(()->"String"+ ++val);
没有Thread
可用于接受任务的实例.因此ExecutorService
将使用创建一个新线程newThread
.它在调用线程中执行此操作main
.由于你newThread
的实现是睡5秒,这正是它的作用.一旦sleep
完成,newThread
将返回Thread
实例,该实例ExecutorService
将启动并执行提交
()->"String"+ ++val
请注意,您的任务仅连接a String
和int
值并返回结果.
将其更改为
Futurefuture = 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
来等待它完成并看到有用的东西.