- 使用
java
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<Integer> future = executorService.submit(() -> {
// 执行一些计算任务
Class<?> clazz = Class.forName("com.example.demo.dao.ItemDao");
System.out.println("Task executed by thread: " + Thread.currentThread().getName());
return 42;
});
Object o = future.get();
System.out.println("Result from task: " + o);
executorService.shutdown();
上述代码首先创建了一个固定核心线程数(最大线程数)大小的线程池。然后调用ExecutorService的submit方法执行一个有返回值的callable任务,该方法返回一个实现Future接口的对象。然后通过future.get()方法获取任务的执行结果。最后关闭线程池。
- 第一行解读
java
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
第一行ExecutorService executorService = Executors.newFixedThreadPool(10);调用了Executors的newFixedThreadPool方法。该方法调用线程池的构造函数创建ThreadPoolExecutor对象。核心线程数和最大线程数均为nThreads。非核心线程存活时间为0L,单位为毫秒。任务队列为LinkedBlockingQueue。
- submit方法解读
java
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
该方法传入要执行的任务task。使用newTaskFor将task封装为RunnableFuture对象。然后调用execute方法执行任务task。该处execute方法调用的是线程池的execute的方法。task的返回值会被赋值给FunnableFuture中的outcome变量。用户使用future.get()方法时,会获取到outcome的值。
- future.get()方法详解
java
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
该方法关键逻辑为report方法。
java
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
report方法根据任务task执行的状态,返回outcome或者异常。