Future 和 Callable 学习小计

2024-01-30 01:30
文章标签 学习 callable future 小计

本文主要是介绍Future 和 Callable 学习小计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Future 和 Callable 学习小计

    • Callable 接口
    • Future 接口
    • Callable 和 Future 的关系
      • get() 方法使用
        • 基础使用
        • 批量使用
        • get(long,TimeUnit) 使用
        • 总结
    • FutureTask 和 Future

在java 中使用Thread 或 Runnable创建线程的时候是无法获取线程的返回结果和抛出异常信息的,但 java 中提供了Future 和 Callable 两个接口的可以实现获取子线程的执行结果。

Callable 接口

  • 类似Runnable,可以被线程池执行的任务
  • 实现call方法
  • 有返回值
    Callable 源码

Future 接口

在这里插入图片描述

  1. get() 任务正常完成,该方法会立即返回结果,任务执行完成之前会一直被阻塞
  2. get(long,TimeUnit) 该方法传入一个延迟的时间和时间单位,如果延迟的时间到了还没有获取到返回结果,则会抛出TimeoutException 异常,在超时异常中任务需要取消
  3. cancel 取消任务执行方法
  4. isDone 返回线程是否执行完毕 ture 完成,返回ture 不代表任务可能是成功的完成,可能任务在执行中发生异常或者被取消
  5. isCancelled 判断任务是否被取消

Callable 和 Future 的关系

  • 可以使用Future.get() 方法 获取 Callable 接口执行的返回结果以及限时获取任务的执行结果
  • 可以通过Future.isDone() 来判断任务是否已经执行完成了,以及取消这个任务
  • 在 Callable 接口中 call() 方法执行完毕之前,主线程调用Future.get() 会被阻塞,直到call() 方法执行完毕后才会获取结果,然后主线程才会切换到runnable 运行状态

get() 方法使用

基础使用
public class FutureDemo {static SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** Future 和 Callable 基础使用方法*/public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(1);// 创建Task 对象, 将实例对象放入到线程池中执行, 并得到 Future 对象Task task = new Task();System.out.println("执行开始时间: " + datetimeFormat.format(new Date()));Future<String> future = executorService.submit(task);// future.get() 获取返回值System.out.println(future.get());System.out.println("返回值值时间: " + datetimeFormat.format(new Date()));executorService.shutdown();}/*** 实现 Callable 接口, 重写 call 方法*/static class Task implements Callable<String> {@Overridepublic String call() throws Exception {Thread.sleep(3000);return "call() return success";}}
}

返回结果
在这里插入图片描述

批量使用

public class FutureDemoArr {static SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");/*** Future 和 Callable 批量提交任务和接收返回值*/public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(2);ArrayList<Future<String>> list = new ArrayList<>();System.out.println("开始时间 : " + datetimeFormat.format(new Date()));// 提交接收返回值for (int i = 0; i < 10; i++) {list.add(executorService.submit(new Task()));}for (Future<String> future : list) {System.out.println(future.get() + "   , 得到返回值的时间 : " + datetimeFormat.format(new Date()));}executorService.shutdown();}/*** 实现 Callable 接口, 重写 call 方法*/static class Task implements Callable<String> {@Overridepublic String call() throws Exception {Thread.sleep(2000);return Thread.currentThread().getName() +  " : " + RandomUtils.nextInt();}}
}

在这里插入图片描述

get(long,TimeUnit) 使用
public class FutureDemoExc {public static void main(String[] args) {// 顾客等待时间int timeout1 = 3000;// 技师返回时间int timeout2 = 5000;Task task = new Task(timeout1, timeout2);Integer num = task.cllNumber();System.out.println("得到的技师: " + num);}/*** Future 和 Callable 发生异常demo, 模仿足疗店点钟场景* 小明 午休时间找个家足疗店想做个足疗,* 小明到了店里告诉商家只等 88 号 3秒, 如果 3 秒不来来个默认的即可*/static class Task implements Callable<Integer> {/*** 顾客等待超时时间*/private Integer timeout1;/*** 88 号技师返回时间*/private Integer timeout2;/*** 默认技师为 1*/private Integer defaultNum = 1;public Task(int timeout1, int timeout2) {this.timeout1 = timeout1;this.timeout2 = timeout2;}public Integer cllNumber() {ExecutorService service = Executors.newFixedThreadPool(1);Future<Integer> future = service.submit(this);try {// 等待返回结果, timeout1 如果超时则抛出 TimeoutException 异常return future.get(timeout1, TimeUnit.MILLISECONDS);} catch (InterruptedException e) {e.printStackTrace();return -1;} catch (ExecutionException e) {e.printStackTrace();return -2;} catch (TimeoutException e) {System.out.println("顾客等待超时 返回默认 ");// 调用 cancel 告诉线程中断future.cancel(true);System.out.println(future.isDone());return defaultNum;} finally {service.shutdown();}}@Overridepublic Integer call() throws Exception {try {Thread.sleep(timeout2);} catch (InterruptedException e) {System.out.println("收到线程中断标识, 返回等不及了返回一个默认的");return 1;}System.out.println(" 88 忙完了 ");return 88;}}
}

返回结果
在这里插入图片描述

总结

将 Callable 实例交给线程池,提交时候线程池会返回一个Future ,这个时候 Future 对象就是一个空的容器,当线程的任务执行结束以后,线程池会立即把结果填入到之前给的Future对象中,这样就可以在Future中得到结果了

FutureTask 和 Future

FutureTask 是用来获取Future和任务的结果的, FuturTask 实际上是Future 的包装器, 可以把Callable 转换成 Future 或 Runnable ,它同时实现了二者的接口。

在这里插入图片描述
将 FutureTask 传给 Thread 使用

 * FutureTask 基础使用*/public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {@Overridepublic String call() throws Exception {Thread.sleep(3000);return "futureTask return success";}});new Thread(futureTask).start();System.out.println(futureTask.get());}

这篇关于Future 和 Callable 学习小计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/658718

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件