java核心-多线程-线程类-Callable、Future和FutureTask
基本概念
<1>Callable,Callable和Runnable差不多,两者都是为那些其实例可能被另一个线程执行的类而设计的,最主要的差别在于Runnable不会
返回线程运算结果,Callable可以(假如线程需要返回运行结果)。
<2>Future,是一个接口表示异步计算的结果,它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。
<3>FutureTask是Future的实现类,也可以说是进阶类,优化了Future的一些缺点,比如Future.get会阻塞等等,它提供了对Future的基本实现。
可使用FutureTask包装Callable或Runnable对象,实现异步处理线程运行结果。FutureTask实现了Runnable和Future(看源码可以看出来),所以也可以
将FutureTask提交给Executor。一般使用FutureTask代替Future即可。使用api
<1>Callable使用方法
call() //类似run()方法
<2>Future使用方法
cancel(boolean mayInterruptIfRunning) //取消任务,如果已经完成,返回false
isCancelled() //判断是否取消过
isDone() //判断是否完成,取消、完成、异常都会返回true
get() //获取执行结果,阻塞的
<3>FutureTask使用方法
cancel(boolean mayInterruptIfRunning)
isCancelled()
done() //重写它来实现异步处理线程执行结果
isDone()
run()
get()
- 使用示例
Callable+Futrue
private static class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("进入CallableThread的call()方法, 开始睡觉, 睡觉时间为" + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("睡觉结束");
return "123";
}
}
@Test
public void test2(){
ExecutorService executorService = Executors.newCachedThreadPool();
CallableThread callableThread = new CallableThread();
long l = System.currentTimeMillis();
System.out.println("任务提交前时间:" + l);
Future<String> submit = executorService.submit(callableThread);
try {
String s = submit.get();
}catch (Exception e){
}
System.out.println("获取结果的时间:" + (System.currentTimeMillis()-l));
}
执行结果
任务提交前时间:1556438172228
进入CallableThread的call()方法, 开始睡觉, 睡觉时间为1556438172229
睡觉结束
获取结果的时间:10006
这里的 Future.get 是阻塞方法 , 会一直等待Callable中线程任务执行完毕,是很低下的效率,
解决方式
1.可以使用FutureTask ,重写done方法
2.循环判断isDone,返回true的时候然后调用get()获取
Callable+FutureTask,异步处理线程运行结果
private static class CallableThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("进入CallableThread的call()方法, 开始睡觉, 睡觉时间为" + System.currentTimeMillis());
Thread.sleep(10000);
System.out.println("睡觉结束");
return "123";
}
}
private class MyFutureTask extends FutureTask<String>{
public MyFutureTask(Callable callable){
super(callable);
}
//FutureTask任务完成,会回调这个方法
@Override
protected void done() {
System.out.println("执行完调用了done()");
super.done();
try {
String s = this.get();
System.out.println("任务执行完毕:" + s);
System.out.println("当前时间:" + System.currentTimeMillis());
}catch (Exception e){
}
}
}
@Test
public void test3() {
ExecutorService executorService = Executors.newCachedThreadPool();
CallableThread callableThread = new CallableThread();
MyFutureTask myFutureTask = new MyFutureTask(callableThread);
executorService.submit(myFutureTask);
System.out.println("主线程执行结束");
try {
executorService.shutdown();
executorService.awaitTermination(12,TimeUnit.SECONDS);
} catch (Exception e) {
}finally {
executorService.shutdownNow();
}
}
执行结果
执行结果如下
主线程执行结束
进入CallableThread的call()方法, 开始睡觉, 睡觉时间为1556416923492
睡觉结束
执行完调用了done()
任务执行完毕:123
当前时间:1556416933493
java核心-多线程-线程类-Callable、Future和FutureTask的更多相关文章
- Java并发编程:ThreadPoolExecutor + Callable + Future(FutureTask) 探知线程的执行状况
如题 (总结要点) 使用ThreadPoolExecutor来创建线程,使用Callable + Future 来执行并探知线程执行情况: V get (long timeout, TimeUnit ...
- java核心-多线程-Java多线程编程涉及到包、类
Java有关多线程编程设计的类主要涉及两个包java.lang和java.util.concurrent两个包 java.lang包,主要是线程基础类 <1>Thread <2> ...
- Java自学-多线程 线程安全的类
Java常见的线程安全相关的面试题 步骤 1 : HashMap和Hashtable的区别 HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式 区别1: HashMap可以 ...
- java核心-多线程(1)-知识大纲
Thread,整理一份多线程知识大纲,大写意 1.概念介绍 线程 进程 并发 2.基础知识介绍 Java线程类 Thread 静态方法&实例方法 Runnable Callable Futur ...
- 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?
重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...
- 2019.12.12 Java的多线程&匿名类
Java基础(深入了解概念为主) 匿名类 定义 Java匿名类很像局部或内联系,只是没有明细.我们可以利用匿名类,同时定义并实例化一个类.只有局部类仅被使用一次时才应该这么做. 匿名类不能有显式定义的 ...
- Java中多线程同步类 CountDownLatch
在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...
- Java基础-多线程-③线程同步之synchronized
使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...
- Java基础-多线程-①线程的创建和启动
简单阐释进程和线程 对于进程最直观的感受应该就是“windows任务管理器”中的进程管理: (计算机原理课上的记忆已经快要模糊了,简单理解一下):一个进程就是一个“执行中的程序”,是程序在计算机上的一 ...
随机推荐
- 周强、张季跃,马凯军《面向对象与程序设计Java》第十四周学习总结
实验十四 Swing图形界面组件 实验时间 20178-11-29 理论部分:不使用布局管理器 有时候可能不想使用任何布局管理器,而只 是想把组件放在一个固定的位置上.下面是将一 个组件定位到某个绝 ...
- Python 安装第三方库中常见问题总结
1.安装某个库时,例如 pip install tinify 出现Permission denied时,在安装命令的最前面添加sudo 例如: sudo pip install tinify 即可. ...
- Lesson Learned
最近,中兴ZTE违反美国商务部禁令,向伊朗出售敏感技术,被美国下达长达7年的禁止令,教训十分深刻.以诚待人,信守承诺,才能在商业社会站稳脚跟. 还是说说最近自己上的一课吧.上了港台服以后,奇奇怪怪的问 ...
- android 判断横竖屏的方法(转)
public boolean isScreenChange() { Configuration mConfiguration = this.getResources().getConfiguratio ...
- aufac在mvc中多线程
注册的时候 将容器放到静态变量中 xxx.IocContainer = builder.Build(); var resolver = new AutofacDepende ...
- flask中注册验证码和分页
注册验证码.核心思路,替换注册页面的img标签的src属性. 1.准备好文件夹:captcha2.导包 from utils.captcha.captcha import captcha3.验证码生成 ...
- JavaScript 之 预编译 作用域,作用域链
第一次写博客,本来是学习jQuery遇到闭包问题,发现并没有理解闭包,发现闭包牵扯的知识点太多.复习了一遍(发现自己该记住的全忘了)写在博客里,自己也是小白,希望大神们指点迷津,必将感激不尽. 我们知 ...
- 20164322 韩玉婷-----Exp6 信息搜索与漏洞扫描
1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具 ...
- 关于使用git上传远程仓库的两种情况(新项目与老项目)
具体的git配置与github仓库ssh配置在这里就不再赘述,本次只讲自己之前遇到的两个内容 1.还没有项目,将远程仓库clone下来直接在里边写项目. 2.已有项目,将已有的项目直接添加到建立好的远 ...
- BLE和2.4G实现通信
1. 背景 客户的项目是无线控制灯具,目前采用2.4G芯片,一端是2.4G遥控器,一端是2.4G灯具.现在客户的需求是在不增加成本的条件下增加手机APP控制.因为BLE芯片一般会比纯2.4G芯片价格高 ...