Callable与Future
本文可作为传智播客《张孝祥-Java多线程与并发库高级应用》的学习笔记。
在前面写的代码中,所有的任务执行也就执行了,run方法的返回值为空。
这一节我们说的Callable就是一个可以带返回值的线程模型。而它的返回值由Future接着。
先看看Callable
java.util.concurrent Interface Callable<V>
接口里面只有一个call方法,参数为空,返回值为T。
首先我们看看javadoc里面 Thread()的构造函数的参数没有Callable类型的,换言之,不能通过Thread().start的方式类运行Callable。
那么如何使用Callable呢?
有一个类叫
public class FutureTask<V> extends Object implements RunnableFuture<V>
其中RunnableFuture实现了Runnable接口。
而Runnable的构造函数的参数却可以使Callable。
说了这么多,我们看看代码:
使用FutureTask
public static void main(String[] args) {
Callable<Integer> callable = new Callable<Integer>() {
public Integer call() throws Exception {
int a=new Random().nextInt(100);
System.out.println(a+" ss");
return a;
}
};
FutureTask<Integer> ft=new FutureTask<Integer>(callable);
// for (int i = 0; i < 5; i++)
// new Thread(ft).start();
// new Thread(ft).start();
ft.run();
try {
System.out.println("得到结果 "+ft.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
运行结果
69 ss
得到结果 69
没有什么问题。
不过大家估计对代码中让new Thread(ft).start()运行5次的部分比较奇怪。
打开注释后,输出的结果还是两行,call方法只运行了一次。为什么?不知道。
我们再看看Future类
带参数的get,就是给个时间限制,如果再n个单位时间内,还没有获得结果,就抛出异常。
使用线程池
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<String> future =
threadPool.submit(
new Callable<String>() {
public String call() throws Exception {
Thread.sleep(2000);
return "hello";
};
}
);
System.out.println("等待结果");
//这里应该有trycatch
System.out.println("拿到结果:" + future.get());
}
结果不再赘述。
多个任务
public static void main(String[] args) {
ExecutorService threadPool2 = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2);
for(int i=1;i<=10;i++){
final int seq = i;
completionService.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
Thread.sleep(new Random().nextInt(5000));
return seq;
}
});
}
for(int i=0;i<10;i++){
System.out.println(completionService.take().get());
//上面本应该有trycatch
}
threadPool2.shutdown();
}
运行结果
3
9
1
6
8
4
7
10
5
2
这句话completionService.take().get()具体是干什么的?
举个例子,你种了10亩地的麦子,等到秋天的时候,你如何割麦子呢?
当然是看那10亩地,那一亩先成熟,就先收割那一亩对吧。
completionService.submit了10个任务,completionService本身也不知道那个任务先执行完。completionService.take()就是获得已经执行完的那个任务的Future。
关于completionservice大家还可以看看下面这个资料
感谢glt
参考资料
http://blog.csdn.net/ghsau/article/details/7451464
Callable与Future的更多相关文章
- java多线程系类:JUC线程池:06之Callable和Future(转)
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java多线程系列--“JUC线程池”06之 Callable和Future
概要 本章介绍线程池中的Callable和Future.Callable 和 Future 简介示例和源码分析(基于JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.co ...
- Java线程(七):Callable和Future
转自:http://blog.csdn.net/ghsau/article/details/7451464 本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果. C ...
- Java并发编程:Callable、Future和FutureTask
作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本博客中未标明转载的文章归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置 ...
- 【原创】JAVA并发编程——Callable和Future源码初探
JAVA多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
CyclicBarrier 接着讲多线程下的其他组件,第一个要讲的就是CyclicBarrier.CyclicBarrier从字面理解是指循环屏障,它可以协同多个线程,让多个线程在这个屏障前等待,直到 ...
- Callable、Future、RunnableFuture、FutureTask的原理及应用
1. Callable.Future.RunnableFuture.FutureTask的继承关系 在多线程编程中,我们一般通过一个实现了Runnable接口的对象来创建一个线程,这个线程在内部会执行 ...
- 并发编程 05—— Callable和Future
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService
前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...
- Java并发(8):CountDownLatch、CyclicBarrier、Semaphore、Callable、Future
CountDownLatch.CyclicBarrier.Semaphore.Callable.Future 都位于java.util.concurrent包下,其中CountDownLatch.C ...
随机推荐
- Spring MVC 实践 - Component
Spring MVC 实践 标签 : Java与Web Converter Spring MVC的数据绑定并非没有任何限制, 有案例表明: Spring在如何正确绑定数据方面是杂乱无章的. 比如: S ...
- 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...
- Playground中格式注释语法
类似于Ruby的ruby document,Xcode的Playground自身也提供一些嵌入文档中的格式注释的语法. 我们先定义一个简单的类: class A{ } 按住opt点击class A,你 ...
- 下载Android源代码编译错误总结
错误1: prebuilts/sdk/api/18.txt:22055: error 9: Removed public method android.telephony.gsm.SmsMessage ...
- Java 单元测试 JUnit4 快速入门
JUnit最佳实践 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class CardServiceTest { /** * 最佳 ...
- (一二九)获取文件的MineType、利用SSZipArchive进行压缩解压
MineType 简介 文件在网络上以二进制流的方式传播,为了区分不同的文件类型,用MineType来标明. 为什么要获取 文件的拓展名较短,比较好记,但是MineType是很长的,比如docx拓展名 ...
- [ExtJS5学习笔记]第三十二节 sencha extjs 5与struts2的ajax交互配置
本文地址:http://blog.csdn.net/sushengmiyan/article/details/43487751 本文作者:sushengmiyan ------------------ ...
- iOS注册远程推送消息证书后提示此证书签发者无效的解决办法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们在编写关于远程推送消息的App时需要注册一个相关的证书,我 ...
- TCP的发送系列 — tcp_sendmsg()的实现(一)
主要内容:Socket发送函数在TCP层的实现 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 上一篇blog讲的是send().sendto().sen ...
- 8.非关系型数据库(Nosql)之mongodb的应用场景
测试脚本: Mysql测试脚本: [php] view plaincopyprint? 1. <?php 2. header("Content-Type:text/html; ...