-
FutureTask
能异步绝不同步,能并行绝不串行
1. Future
一个Future代表一个异步计算的结果。Future提供检查计算是否完成、等待计算完成并获取计算结果的方法。只有当计算完成以后,才可以使用get方法检索结果,否则将会阻塞直到计算完成。通过调研cancel方法可以取消执行。另外,还提供了检查任务是正常完成还是被取消的方法。一旦计算完成,这个计算不能被取消。
简单用法:
1 public class App {
2 ExecutorService executorService = Executors.newFixedThreadPool(3);
3 ArchiveSearcher searcher = new ArchiveSearcher();
4
5 void showSearch(final String target) throws InterruptedException {
6 Future<String> future = executorService.submit(new Callable<String>() {
7 public String call() {
8 return searcher.search(target);
9 }
10 });
11
12 displayOtherThings(); // do other things while searching
13
14 try {
15 displayText(future.get()); // use future
16 } catch (ExecutionException ex) {
17 cleanup();
18 return;
19 }
20 }
21 }
FutureTask类是Future的实现,它同时也实现了Runnable,因此也可以被Executor执行。例如,上面的代码可以被改写成如下:
1 FutureTask<String> future = new FutureTask<String>(new Callable<String>() {
2 public String call() {
3 return searcher.search(target);
4 }
5 });
6 executor.execute(future);
2. FutureTask
- 一个可取消的异步计算
- 该类提供了Future的基本实现,提供了启动和取消计算、查询计算是否完成以及检索计算结果的方法
- 只有在计算完成后才可检索结果;如果计算尚未完成,get方法将阻塞
- 计算完成以后,计算不能重启或取消(除非调用runAndReset方法)
一个FutureTask可以用来包装一个Callable或Runnable对象。因为FutureTask实现了Runnable接口,一个FutureTask可以被提交给一个Executor来执行。
3. 示例
1 package com.cjs.example;
2
3 import java.util.concurrent.*;
4
5 /**
6 * @author ChengJianSheng
7 * @date 2019-05-22
8 */
9 public class App {
10
11 public static void main(String[] args) throws Exception {
12
13 long t1 = System.currentTimeMillis();
14
15 ExecutorService executorService = Executors.newFixedThreadPool(3);
16
17 FutureTask<String> heatUpWaterFuture = new FutureTask<String>(new Callable<String>() {
18 @Override
19 public String call() throws Exception {
20 System.out.println("烧开水...");
21 Thread.sleep(3000);
22 return "ok";
23 }
24 });
25
26
27 FutureTask<String> cookMealsFuture = new FutureTask<String>(new Callable<String>() {
28 @Override
29 public String call() throws Exception {
30 System.out.println("煮饭...");
31 Thread.sleep(5000);
32 return "ok";
33 }
34 });
35
36 executorService.submit(heatUpWaterFuture);
37 executorService.submit(cookMealsFuture);
38
39 System.out.println("炒菜...");
40
41 Thread.sleep(2000);
42
43 System.out.println("菜炒好了了");
44
45 if (heatUpWaterFuture.get(5000, TimeUnit.SECONDS) == "ok"
46 && cookMealsFuture.get(5000, TimeUnit.SECONDS) == "ok") {
47 System.out.println("开饭了...");
48 }
49
50 long t2 = System.currentTimeMillis();
51 System.out.println("做饭用时:" + (t2-t1) + "ms");
52
53 }
54 }
输出
1 烧开水...
2 煮饭...
3 炒菜...
4 菜炒好了了
5 开饭了...
6 做饭用时:5014ms
在实际开发过程中,将那些耗时较长,且可以并行的操作都封装成一个FutureTask(比如:有的数据通过调用dubbo服务获取,有的数据需要从缓存中读取,有的数据需要复杂的计算)
原文:https://www.cnblogs.com/cjsblog/p/10905263.html
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
JavaScript判断两个数组相等的四类方法
js如何操作video标签
React实战--利用甘特图和看板,强化Paas平
【记录】正则替换的偏方
前端下载 Blob 类型整理
抽象语法树AST必知必会
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程