naw*_*low -2 java concurrency multithreading
由于某种原因,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<String> 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());
}
}
Run Code Online (Sandbox Code Playgroud)
并输出:
应用开始时间: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);
Run Code Online (Sandbox Code Playgroud)
没有Thread可用于接受任务的实例.因此ExecutorService将使用创建一个新线程newThread.它在调用线程中执行此操作main.由于你newThread的实现是睡5秒,这正是它的作用.一旦sleep完成,newThread将返回Thread实例,该实例ExecutorService将启动并执行提交
()->"String"+ ++val
Run Code Online (Sandbox Code Playgroud)
请注意,您的任务仅连接a String和int值并返回结果.
将其更改为
Future<String> future = completionService.submit(() -> "String" + ++val + " Thread " + Thread.currentThread());
System.out.println("All tasks submitted at: " + new Date());
System.out.println("Future returned: " + future.get());
Run Code Online (Sandbox Code Playgroud)
调用get返回Future来等待它完成并看到有用的东西.