并发-9-Callable和Future
我们原来所说的继承Thread或者实现Runnable的方式都无法获得线程的执行结果,除非使用共享变量或者线程通信,我们先看一下Runnable接口的源码:
public interface Runnable{public abstract void run(){}
}
复制代码
run()的返回值为void,在任务执行完之后没有返回
继承Thread和实现Runnable这两种方式,都无法获得线程执行的结果
Callable可以弥补这一个缺点:
public interface Callable<V>{V call() throws Exception
}复制代码
是一个泛型接口,返回值类型为传入进来的的T类型的值
注意:Callable中方法是call而不是run
使用Callable
一般配合ExecutorService来使用:
其中声明了若干个重载的submit方法
<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result); //一般不使用Future<?> submit(Runnable task);
复制代码
Future
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果
public interface Future<V> {boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled();boolean isDone();V get() throws InterruptedException, ExecutionException;V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;}复制代码
cancel:取消任务
mayInterruptIfRunning:是否可以取消正在执行的任务
isCancelled:是否成功取消
isDone:是否已经完成
get:获取执行结果,一直等到任务执行完毕才返回,阻塞等待
get(long timeout, TimeUint unit):用来获取执行结果,指定时间内,还没有获取到结果,就返回null
也就是说Future用于异步获取执行结果或取消执行任务提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
FutureTask是Future的唯一实现
public interface RunnableFuture<V> extends Runnbale,Future<V>void run()
}public class FutureTask implements RunnbaleFuture<V>{public FutureTask(Callable<V> callable)public FutureTask(Runnable runnable,V result)
}复制代码
可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
这段代码不给答案啦,动手实践感受一下
public class FutureTaskUseDemo {public static void main(String[] agrs) throws InterruptedException, ExecutionException {ExecutorService executor = Executors.newCachedThreadPool();/*** 使用FutureTask的Runnable特性*/Thread thread = new Thread(new FutureTask<>(new BoilWater()));thread.start();/*** 使用FutureTask的Callable特性------第一种写法*/FutureTask futureTask = new FutureTask(new BoilWater());executor.submit(futureTask);out.println("做饭");Thread.sleep(2000);out.println("饭做好了");while (!futureTask.isDone()) {out.println("水还没烧开呢");Thread.sleep(1000);}out.println(futureTask.get());/*** 使用FutureTask的Callable特性------第二种写法*/Future<String> submit = executor.submit(new BoilWater());out.println("做饭");Thread.sleep(2000);out.println("饭做好了");while (!submit.isDone()) {out.println("水还没烧开呢");Thread.sleep(1000);}out.println(submit.get());/*** 多个任务同时并行*/CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(executor);for (int i = 0; i < 5; i++) {final int taskId = i;cs.submit(() -> taskId);}for (int i = 0; i < 5; i++) {try {out.println(cs.take().get());} catch (Exception e) {}}}
}class BoilWater implements Callable<String> {@Overridepublic String call() throws Exception {Thread.sleep(5000);return System.currentTimeMillis() + " 水烧开了";}
}
复制代码
并发-9-Callable和Future相关推荐
- 15、Java并发编程:Callable、Future和FutureTask
Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...
- futuretask java 并发请求_Java并发编程:Callable、Future和FutureTask
Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...
- futuretask java 并发请求_Java并发机制(9)--Callable、Future、FutureTask的使用
Java并发编程:Callable.Future.FutureTask的使用 继承关系: 1.接口Callable与Runnable 1.1.Runnable接口中只有一个void run()方法,其 ...
- 【Java并发】Runnable、Callable、Future、FutureTask
创建线程的两种方式 直接继承 Thread 实现 Runnable 接口 这两种方式都有一个缺点:在执行完成任务之后,无法直接获取到最后的执行结果.如果需要获取执行结果,就必须通过共享变量或线程通信的 ...
- Java高并发编程:Callable、Future和FutureTask
1. Callable 泛型接口,用于获取线程执行完的结果,Callable的声明如下 public interface Callable<V> {// 返回 V 类型的结果V call( ...
- futuretask java 并发请求_【Java并发】Runnable、Callable、Future、FutureTask
创建线程的两种方式 直接继承 Thread 实现 Runnable 接口 这两种方式都有一个缺点:在执行完成任务之后,无法直接获取到最后的执行结果.如果需要获取执行结果,就必须通过共享变量或线程通信的 ...
- Java并发编程:Callable、Future和FutureTask
在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需要获取执行结果,就 ...
- 一次搞懂 Runnable、Callable、Future、FutureTask,不懂不要钱!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 一般创建线程只有两种方式,一种是继承Thread,一种是实 ...
- Callable和Future
接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. Callable接口类似于Runnable,从名字就可以看出来了, ...
- Callable和Future、FutureTask的使用
http://www.silencedut.com/2016/06/15/Callable%E5%92%8CFuture%E3%80%81FutureTask%E7%9A%84%E4%BD%BF%E7 ...
最新文章
- 1126 Eulerian Path
- (六)java多线程之ReadWriteLock
- 警告:攻击者利用 SonarQube 漏洞盗取国内多个机构的大量源码!
- angularjs与PHP,我应该混合AngularJS与PHP框架吗?
- oracle M4,oracle高级部分 - osc_9gm4ypss的个人空间 - OSCHINA - 中文开源技术交流社区...
- Sublime Text 关闭自动更新
- 前端学习(568):元素定高 容器定高 为什么不能居中
- hibernate和struts实现分页
- Warning:mailcious javascript detected on this domain来由
- matlab信源编码,常见无失真信源编码算法及Matlab实现比较(27页)-原创力文档
- CAD的菜单栏消失,如何再次调出来
- button加下划线
- 注册表中shell文件不见了_win10系统注册表中的shell文件不小心被删除的恢复教程...
- 今日头条的排名算法_今日头条旗下悟空问答的排名算法规则
- hbase 0.98.1集群安装
- 你是否知到西游记中孙悟空的师傅是什么人?
- 智能无感验证实战案例:神州优车
- 使用 LaTeX 的笔记
- SAP MM02主数据维护多语言长文本,丢失空格的解决办法
- Freemarker使用mht制作导出word模板
热门文章
- Ubuntu系统在VMware虚拟机中显示显示过小
- COALESCE在SQL拼接中的大用途
- document.getElementById()和document.forms[0].submit()
- 一分钟学会spring注解之@Scope注解
- C# 检测文件是否被其他进程占用
- mysql字段类型、范围详解
- 边看chromium的代码,边想骂人...
- 《ASP.NET 开发从入门到精通》----2.3 编译和部署ASP.NET程序
- RealPlayer 15正式发布 简体中文版下载
- MSDynamicsAX2009成本处理与重估(中文)