Callable接口和Future接口
来源:互联网 发布:阴线买入公式源码 编辑:程序博客网 时间:2024/05/01 23:18
1.Callable和Future
Callable作用和Runnable类似,但是有返回值。对应Runnable接口的run方法,它有个call方法
V call()
throws Exception
Future用于保存线程异步计算的结果,它最重要的方法是
V get()
throws InterruptedException,
ExecutionException
用于获取运算结果,它在调用时被阻塞,直到运算完成。可以被打断。
Future往往和Callable结合使用。
执行一个有返回值的任务步骤如下:
1.新建一个任务,实现Callable接口
2.用ExecutorService的submit方法提交任务
3.任务返回的计算结果是一个Future对象,调用Future对象的get获取结果
以下例子用线程池启动10个任务,并依次打印他们的返回值。
public class CallableDemo {public static void main(String[] args) {ExecutorService exec = Executors.newCachedThreadPool();ArrayList<Future<String>> results =new ArrayList<Future<String>>();for (int i = 0; i < 10; i++) {results.add(exec.submit(new TaskWithResult(i)));}for (Future<String> fs : results) {try {System.out.println(fs.get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}finally {exec.shutdown();}}}}class TaskWithResult implements Callable<String> {private int id;public TaskWithResult(int id) {this.id = id;}//有返回结果的方法@Overridepublic String call() {return "result of TaskWithResult" + id;}}输出:
result of TaskWithResult0
result of TaskWithResult1
result of TaskWithResult2
result of TaskWithResult3
result of TaskWithResult4
result of TaskWithResult5
result of TaskWithResult6
result of TaskWithResult7
result of TaskWithResult8
result of TaskWithResult9
2.FutureTask包装器
FutureTask可以将Callable转换成Future和Runnable,它同时实现了2个的接口:
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>
以下的例子实现了统计指定目录下包含关键字的文件数目,
它用FutureTask对象包装一个Callable,启动任务进行统计,任务的call方法中采用递归的方式,遇到目录则再次启动一个线程,传入FutureTask包装的任务,获取运行的Future对象。如果遇到的是单个文件,则对文件进行统计。最后将所有统计结果(对于单个文件的count和目录的future list中的每个count)相加。
虽然get方法是阻塞的,但是在递归中启动了多个线程,其实他们是同时工作的,所以执行速度不会很慢。
public class FutureTest {public static void main(String[] args) throws Exception {Scanner in = new Scanner(System.in);System.out.print("输入目录:");String directory = in.nextLine();System.out.print("输入关键词:");String keyword = in.nextLine();MatchCounter counter = new MatchCounter(new File(directory), keyword);FutureTask<Integer> task = new FutureTask<Integer>(counter);ExecutorService executor = Executors.newSingleThreadExecutor();executor.execute(task);System.out.println("一共有"+ task.get() +"个匹配的文件");}}class MatchCounter implements Callable<Integer> {private File directory;private String keyword;private int count;public MatchCounter(File directory, String keyword) {this.directory = directory;this.keyword = keyword;}@Overridepublic Integer call() throws Exception {count = 0;try {File[] files = directory.listFiles();ArrayList<Future<Integer>> results =new ArrayList<Future<Integer>>();for (File file : files) {if (file.isDirectory()) {MatchCounter counter = new MatchCounter(file, keyword);FutureTask<Integer> task = new FutureTask<Integer>(counter);results.add(task);ExecutorService executor = Executors.newSingleThreadExecutor();executor.execute(task);} else {if (search(file)) {count++;}}}for (Future<Integer> result : results) {try {count += result.get();} catch (Exception e) {}}} catch (Exception e) {}return count;}public boolean search(File file) {try {Scanner inScanner = new Scanner(new FileInputStream(file));boolean found = false;while (!found && inScanner.hasNextLine()) {String line = inScanner.nextLine();if (line.contains(keyword)) {found = true;}}inScanner.close();return found;}catch (IOException e){return false;}}}运行结果:
输入目录:F:/log
输入关键词:a
一共有1个匹配的文件
- Callable接口和Future接口
- Callable接口和Future接口
- Callable和future接口详解
- Callable 和Future 接口使用
- Future接口和Callable接口的使用
- Callable与future接口
- Concurrent, Callable 和 Future接口比较
- Java接口:Callable 与 Future
- Callable、Future、FutureTask接口初探
- Runnable、Callable、Future接口区别
- Java多线程之Callable和Future接口的实现
- java ExecutorService 线程池Callable 和 Future接口
- 并发编程之Callable和Future接口、FutureTask类
- Java并发编程-Executor框架之Callable和Future接口
- Java并发编程-Executor框架之Callable和Future接口
- Java Callable Future接口执行机制解密
- Java 多线程设置线程超时时间之 Callable接口和Future接口
- Java 多线程设置线程超时时间之 Callable接口和Future接口
- iOS Constraint错误
- Ubuntu13.04 新手总结(时刻更新)
- 使用jxl模版导出时出现的问题总结
- 在VB6里怎样调用VBA里的函数?
- Linux Support for ARM LPAE - eLinux.org
- Callable接口和Future接口
- 获取更多
- 66. 防止错误
- Jmeter 线程组之一
- 使用 LLVM 框架创建一个工作编译器,第 1 部分
- java中常用的字符串的截取方法
- 经典数据结构之稀疏矩阵
- Media player service not published, waiting...
- 数据库命名规范(适用SQL Server)