【原创】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模式
自己对线程池的理解: coresize 3 maxsize 5 blockLinkedQuenue 3 当提交的任务在<=3时,创建三个线程干活 大于3时,把任务先加入阻塞式队列,当有空闲的核心 ...
- Java并发编程中线程池源码分析及使用
当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...
- Java并发编程笔记之FutureTask源码分析
FutureTask可用于异步获取执行结果或取消执行任务的场景.通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过Fu ...
- Java并发编程笔记之CopyOnWriteArrayList源码分析
并发包中并发List只有CopyOnWriteArrayList这一个,CopyOnWriteArrayList是一个线程安全的ArrayList,对其进行修改操作和元素迭代操作都是在底层创建一个拷贝 ...
- Java并发编程笔记之ThreadLocalRandom源码分析
JDK 并发包中 ThreadLocalRandom 类原理剖析,经常使用的随机数生成器 Random 类的原理是什么?及其局限性是什么?ThreadLocalRandom 是如何利用 ThreadL ...
- Java并发编程笔记之ThreadLocal源码分析
多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的,多线程访问同一个共享变量特别容易出现并发问题,特别是多个线程需要对一个共享变量进行写入时候, ...
- Java并发编程笔记之SimpleDateFormat源码分析
SimpleDateFormat 是 Java 提供的一个格式化和解析日期的工具类,日常开发中应该经常会用到,但是由于它是线程不安全的,多线程公用一个 SimpleDateFormat 实例对日期进行 ...
- Java并发编程笔记之Timer源码分析
timer在JDK里面,是很早的一个API了.具有延时的,并具有周期性的任务,在newScheduledThreadPool出来之前我们一般会用Timer和TimerTask来做,但是Timer存在一 ...
- Java并发编程笔记之CyclicBarrier源码分析
JUC 中 回环屏障 CyclicBarrier 的使用与分析,它也可以实现像 CountDownLatch 一样让一组线程全部到达一个状态后再全部同时执行,但是 CyclicBarrier 可以被复 ...
随机推荐
- Struts框架——(二)Struts原理with登录实例
二. Struts基本工作流程 假设现在有以下情景: 用户正在浏览一个用STRUTS的技术构建的网站主页,主页上有个登陆表单,用户填好登陆名和密码,单击"登陆"按钮,就激活了以下一 ...
- SQL中EXISTS怎么用[转]
SQL中EXISTS怎么用 1 2 3 4 分步阅读 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False 方法/步骤 1 EXISTS用于 ...
- 【好文要转】HTTP图解(大牛必经之路)
http://www.cnblogs.com/aylin/p/6221436.html
- vue路由的简单实例
vue2.0 和 vue1.0 路由的语法还是有点稍微的差别,下面介绍一下vue-router 2的简单实例: <!DOCTYPE html> <html lang="en ...
- 给div设置background-color: rgba(0, 0, 0, 0.2)属性,并加了css3动画--opacity动画淡出动画,之后div子元素的字体会抖一下
问题:给div设置background-color: rgba(0, 0, 0, 0.2)属性,并加了css3动画--opacity动画淡出动画,之后div子元素的字体会抖一下: 解决:animati ...
- vs2015 现用插件
1.abphelper abp app自动生成接口和input output 2.ankhsvn svn插件 3.c#outline2015 大括号折叠 4.codemaid 格式化 5.go to ...
- SVN服务器与测试服务器代码同步
在本地做测试项目的时候,想svn提交和服务器上的代码一步到位,不想再手动更新一次了,所以就研究了下同步, 要实现svn提交后自动更新到测试服务器,在你的版本库下的hooks文件夹下添加post-com ...
- C# 文件操作 把文件读取到字节数组
string zipfile = "c:\\a.zip"; //方法1 FileStream fs = new FileStream(zipfile, FileMode.Open) ...
- es6之set和map
1.set ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值,set本身就是构造函数,所以可以通过new的方式来创建对象 // 例一 可以做数组去重用 var set ...
- 安装JDK,Python SDK及环境变量的配置
JDK 首先是下载安装包 http://pan.baidu.com/share/link?shareid=3261115669&uk=369127748 一般JDK和Jre是一起安装的,提醒大 ...