原创JAVA并发编程——Callable和Future源码初探
Posted 陈旭猴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创JAVA并发编程——Callable和Future源码初探相关的知识,希望对你有一定的参考价值。
JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。
thread和runnable不讨论了。 太多地方可以找到他们的探究了
重点看callable和future,
先上一段代码:
package com.future.chenjun.test; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Test { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); MyTask myTask = new MyTask(); Future<Integer> result = executorService.submit(myTask); executorService.shutdown(); try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主线程在执行任务"); try { System.out.println("task运行结果" + result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任务执行完毕"); } } class MyTask implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("子线程在进行计算"); Thread.sleep(3000); int sum = 0; for (int i = 0; i < 100; i++) sum += i; return sum; } }
首先分析main()函数第一行 ,这很重要
ExecutorService executorService = Executors.newCachedThreadPool();
自然引出问题1: ExecutorService 本身是一个接口,那
executorService这个引用到底指向了哪个实现类? 这个问题so easy,直接进JDK源码看结果
我们看到实现代码如下:
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
答案一目了然,根据多态原理无疑这个
ThreadPoolExecutor 就是 ExecutorService的子类。
好,这个问题就此打住,记住结论:
线索1: ThreadPoolExecutor 就是 ExecutorService的子类。
接下来看main()函数的第三行 :
Future<Integer> result = executorService.submit(myTask);
稍微变一下形式,如下
Future<Integer> result = executorService.submit(new Callable<Integer>(){ @Override public Integer call() throws Exception{ } });
look ,和如下代码异曲同工
new Thread(new Runnable(){ //匿名内部类实现XXX
public void run(){
}
});
OK 看一下这个submit到底做了什么事
我进ThreadPoolExecutor里面一看,卧槽,发现里面没有submit方法,见鬼了
别急,我翻一下 ThreadPoolExecutor 类声明
发现如下声明
public class ThreadPoolExecutor extends AbstractExecutorService
我好奇的打开抽象类AbstractExecutorService.CLASS的源码,莫非这submit藏在这里了
打开了。。。。
终于找到了submit方法,如下
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
然后我们自然要搞清楚,这个RunnableFuture是什么鬼,打开它的源码,我们看到:
public interface RunnableFuture<V> extends Runnable, Future<V> { /** * Sets this Future to the result of its computation * unless it has been cancelled. */ void run(); }
原来如此,他是Runnable, Future<V>的子接口
暂时告一段落,理一下思绪
以上是关于原创JAVA并发编程——Callable和Future源码初探的主要内容,如果未能解决你的问题,请参考以下文章
JAVA 并发编程-返回运行结果(Callable和Future)
Java 并发编程——Callable+Future+FutureTask
Java并发编程 - Executor,Executors,ExecutorService, CompletionServie,Future,Callable