关于多线程Callable和Future
来源:互联网 发布:微软亚洲研究院 知乎 编辑:程序博客网 时间:2024/06/05 09:02
---------------------- android培训、java培训、期待与您交流! ---------------------- 关于多线程Callable和Future 实现多线程我们可以继承Thread类或者实现Runnable接口,通过Thread类把run()方法包装成线程执行体,但是这两种方法都不能直接把任意方法直接包装成线程执行体,比如说一个带返回值的方法,或者一个抛异常的方法。 从Java 5开始,Java提供了Callable接口,该接口是Runnable接口的增强版,Callable接口提供了一个call()方法,可以作为线程执行体,但call()方法比run()方法的功能更强大。call()方法可以有返回值。call()方法可以声明抛出异常。因此我们完全可以提供一个Callable对象作为Thread的target,而该线程的线程执行体就是Callable对象的call()方法。 通过查阅API发现,Callable接口是java 5新增的接口,而他不是Runnable接口的子接口,所以Callable对象不能直接作为Thread类的target。而且Callable方法还有一个返回值——call()方法,不能直接调用,它是作为线程执行体才被调用的。 在工具开发包中,java 5 提供了Future接口来代表Callable接口里的call()方法的返回值,并且为Future接口提供了一个FutureTask实现类,该实现类实现了Future接口,并且实现了Runnable接口——可以作为Thread类的target。实际上这里的FutureTask类实现了一个桥梁的作用,用于连接Callable对象和Thread对象。需要注意的是Callable接口有泛型限制,Callable接口里的泛型形参类型,与call()方法的返回值类型相同。接口 Callable<V>V call() throws Exception 计算结果,如果无法计算结果,则抛出一个异常。类 FutureTask<V> V - 此 FutureTask 的 get 方法所返回的结果类型。public V get() throws InterruptedException,ExecutionException 如有必要,等待计算完成,然后获取其结果。创建并启动有返回值的线程步骤与实现Runnable接口相似:1.创建Callable接口的实现类,并实现call()方法2.创建Callable实现类的实例,使用FutureTask类来包装Callable对象3.使用FutrueTask对象作为Thread对象的target创建并启动新线程。4.调用FutrueTask对象的get()方法来获得子线程执行结束后的返回值。例:[java] view plain copyimport java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class ThirdThread implements Callable<Integer>{ public Integer call(){ int i = 0; for( ; i<60; i ++){ System.out.println(Thread.currentThread().getName() + "循环变量i的值是 : " + i); } return i; } public static void main(String[] args) { ThirdThread rt = new ThirdThread(); //创建Callable对象 FutureTask<Integer> task = new FutureTask<Integer>(rt);//使用FutrueTask来包装Callable对象 for(int i=0 ; i<60 ; i++){ System.out.println(Thread.currentThread().getName() + "-------" + i); if(i == 10){ new Thread(task, "有返回值的线程").start(); //实际上还是以Callable对象创建并启动线程 } } try{ System.out.println("子线程的返回值 :" + task.get()); } catch(Exception e){ e.printStackTrace(); } } } 总结: 通过继承Thread类或实现Runnable、Callable接口都可以实现多线程,不过实现Runnable接口与实现Callable接口的方式基本相同,只是Callable接口里定义的方法有返回值,可以声明抛出异常而已。采用实现Runnable、Callable接口的方式创建多线程,线程类只是实现了Runnable接口或Callable接口,还可以继承其他类在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将 CPU、代码和数据分开,形成清晰的模型,较好的体现了面向对象的思想。 个人理解:可以把Thread类理解成代工厂,而Runnable接口则是原材料,工厂只负责将符合标准的原材料加工成成品,而Callable接口则是另一种材料,他需要先被FutrueTask加工成半成品(即符合Runnable标准的材料),然后在交给Thread工厂加工。
再加上一个自己写的例子
package cn.I.Calls;
import java.util.Date;
import java.util.concurrent.Callable;
public class Calls implements Callable<Object> {
private String taskNum;
Calls(String taskNum) {
this.taskNum = taskNum;
}
public Object call() throws Exception {
System.out.println(">>>" + taskNum + "任务启动");
Date dateTmp1 = new Date();
Thread.sleep(1000);
Date dateTmp2 = new Date();
long time = dateTmp2.getTime() - dateTmp1.getTime();
System.out.println(">>>" + taskNum + "任务终止");
return taskNum + "任务返回结果,当前任务时间" + time + "毫秒";
}
}
package cn.I.Calls;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Test {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
System.out.println("程序开始运行-----");
Date date1 = new Date();
int taskSize = 5;
// 创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
List<Future> list = new ArrayList<Future>();
for (int i = 0; i < taskSize; i++) {
Callable c = new Calls(i + " ");
// 执行任务并获取Future对象
Future f = pool.submit(c);
list.add(f);
}
// 关闭线程池
pool.shutdown();
// 获取所有并发任务的运行结果
for (Future f : list) {
// 从Future对象上获取任务的返回值,并输出到控制台
System.out.println(">>>" + f.get().toString());
}
Date date2 = new Date();
System.out.println("-----程序运行结束---运行时间="
+ (date2.getTime() - date1.getTime()));
}
}
- 关于多线程Callable和Future
- 多线程Callable和Future
- 多线程 :Callable和Future
- java多线程Callable和Future
- Java多线程--Callable和Future
- Java多线程之 Callable、Future和FutureTask
- java多线程Future和Callable用法
- Java 多线程线程池 - Callable和Future
- java多线程 callable和future学习
- Java多线程之Callable和Future
- Java多线程之Callable、Future和FutureTask
- java多线程之Callable和Future
- 多线程编程入门(11):Callable和Future
- Java多线程:Callable、Future和FutureTask
- 多线程(九)Callable、Future和FutureTask
- java多线程之Callable和Future
- Java多线程系列--Callable和Future
- Java多线程:Callable、Future和FutureTask
- 3668: [Noi2014]起床困难综合症
- 35 个 Java 代码性能优化总结
- Linux 错误:delimited by end-of-file (wanted `EOF')
- hdu魔板 康拓展开
- JAVA多线程实现的三种方式
- 关于多线程Callable和Future
- 多线程下的Socket网络通信
- 多线程BaseDao实现在同一内存中实现多个连接对象
- POJ3233---Matrix Power Series (矩阵快速幂(升级):矩阵套矩阵)
- 多线程三种方式2
- 各种多线程
- 多线程
- 维数灾难
- 3172: [Tjoi2013]单词