java异步回调历程
java I/O的经历了BIO(Blocking IO),NIO(Non-blocking IO),AIO(Async-I/O),这些IO技术的发展都是依托已java版本的更新。
本文主要研究一下java的异步回调机制,
主要针对juc包下的Future,Callable,FutureTask,更多关于java I/O历程。
**业务场景 **
假定我们有这样一个业务场景,烧一壶开水,烧一壶开水有如下几个步骤:
- 加水
- 打开煤气
- 烧水ing—(比较耗时的动作)
- 观察,烧水完成
- 最后水开之后,关闭煤气
AbstractBoilWater
public abstract class AbstractBoilWater {protected volatile boolean isReadyFlag = false;protected void a_addWater() {System.out.println("1.加水");}protected void b_on() {System.out.println("2.打开煤气");}protected void c_boiling() throws Exception {System.out.println("3-1.烧水中.....");Thread.sleep(5000); //模拟烧水的过程,比较耗时System.out.println("3-2.水开了");isReadyFlag = true;}protected void d_off() {System.out.println("4.关闭煤气");}//烧水方法public abstract void make() throws Exception;protected void playGame() throws Exception {Thread.sleep(1200);if (!isReadyFlag) {System.out.println("水还没烧开,玩一把游戏");}}}
编写一个抽象类AbstractBoilWater,
其中c_boiling()模拟一个烧水的过程,比较耗时;
提供一个抽象方法make(),各个子类通过重写该方法,用自己的方式来花式烧水。
方法一:同步等待
方法一的实现步骤如下:
- a.加入适量的水
- b.打开煤气
- c.暗中观察,等待水烧开 —同步阻塞等待
- d.关闭煤气
代码一
public class BioBoilWater extends AbstractBoilWater{@Overridepublic void make() throws Exception {a_addWater();b_on();c_boiling();//同步阻塞等待d_off();}
}
,由代码可见在烧水的过程中,一直在同步阻塞等待,烧水的这一段时间就白白浪费了。
方法二:Future,Callable-异步执行,同步回调
- a.加入适量的水
- b.打开煤气 — 老鸟有一定的经验,目测20分钟之后可以烧开,
- c.playGame// 打一局小游戏
- d.观察水是否烧开烧开
- e.关闭煤气
方法二代码
public class NioBoilWater extends AbstractBoilWater{@Overridepublic void make() throws Exception {ExecutorService executor = Executors.newCachedThreadPool();a_addWater();b_on();Future<Integer> future = executor.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {c_boiling();return 1;}});executor.shutdown();while(!future.isDone()){playGame();//烧水过程中,玩一局游戏}int a = future.get(); //同步阻塞等待d_off();}
}
启动一个新的线程去执行c_boiling(),执行过程中,无需同步的阻塞等待,可以去做一些其他一些有意思的事,打游戏playGame(); 最终使用future.get(),这是一个同步阻塞的操作,等待Callable事件完成。
这里注意的一点:Future只能用线程池去调用执行。
Future源码解析
public interface Future<V> {//终止当前任务boolean cancel(boolean mayInterruptIfRunning);//Returns {@code true} if this task was cancelled before it completedboolean isCancelled();//正常完成,异常,cancel;boolean isDone();/*** Waits if necessary for the computation to complete, and then* retrieves its result.** @return the computed result* @throws CancellationException if the computation was cancelled* @throws ExecutionException if the computation threw an* exception* @throws InterruptedException if the current thread was interrupted* while waiting*/V get() throws InterruptedException, ExecutionException;//阻塞--最大等待时间V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}
方法三:FutureTask-异步执行,异步回调
- a.加入适量的水
- b.打开煤气
- c.playGame // 打一局小游戏
- d.主动提醒,水已烧开 ---- //主动通知-回调
- e.关闭煤气
方法三代码
public class AioBoilWater extends AbstractBoilWater {@Overridepublic void make() throws Exception {a_addWater();b_on();FutureTask<Integer> futureTask = new FutureTask(() -> {c_boiling();return 1;}){//当futureTask执行完之后,调用done()@Overrideprotected void done() {d_off();}};new Thread(futureTask).start();while(!futureTask.isDone()){playGame();}
// futureTask.get();//阻塞,Thread.sleep(5000);}
}
FutureTask源码分析
,FutureTask实现了Future和Runnable接口, 它可以不适用线程池,直接通过线程启动。
它最大的特点是,它有一个done()回调函数,当前任务状态为isDone时,触发。
protected void done() {}
方法四:CompletableFuture-异步执行,异步回调
使用jdk8新特性:CompletableFuture
public class CompletableFutureBiolWater extends AbstractBoilWater {@Overridepublic void make() throws Exception {a_addWater();b_on();CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {try {c_boiling();} catch (Exception e) {e.printStackTrace();}return 1;});//注册事件“监听”future.whenComplete((v, e) -> {/* System.out.println(v);System.out.println(e);*/d_off();});while (!future.isDone()) {playGame();}}
}
java异步回调历程相关推荐
- Java 异步回调机制实例解析
2019独角兽企业重金招聘Python工程师标准>>> 一.什么是回调 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步调用. 回调是一种特殊 ...
- java异步回调讲解
所谓回调:就是A类中调用B类中的某个方法M1,然后B类中反过来调用A类中的方法M2,M2这个方法就叫回调方法.实际在使用的时候,也会有不同的回调形式,这里主要讲一下异步回调形式. Class A实现接 ...
- java filter 回调_Java 异步回调机制实例分析
Java 异步回调机制 一.什么是回调 回调,回调.要先有调用,才有调用者和被调用者之间的回调.所以在百度百科中是这样的: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用 ...
- c++ 异步回调_知道Java中的回调机制吗?
调用和回调机制 在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种: 1.同步调用 同步调用是最基本并且最简单的一种调用方式, 类A的方法a()调用类B的方法b( ...
- java线程callback,Java线程之异步回调(Callback)
●介绍 有时候执行一个任务需要很长时间,单线程下线程会处于阻塞状态.这个时候我们会考虑一种非阻塞的处理模式.非阻塞任务在任何编程语言里都必不可少,Java也不例外.多线程就是一个很好的解决办法. 但是 ...
- java异步多线程 判断线程状态_java多线程和异步回调
在实际开发过程中遇到的多线程情况不多,但是在生产环境中多线程是最基本的情况,java面试时也会考到,所以看看多线程的知识还是很有必要的. Thread,Runnable,Callable,Future ...
- java 中的异步回调
异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作 ...
- Java接口回调,异步回调理解
文章目录 前言 一.回调简单理解 二.Java中用接口实现回调 1.实现接口回调 1.1同步回调 1.2 异步回调 2.为啥要用接口实现 3.关于接口(基础) 总结 前言 本文是作者在学习接口回调时看 ...
- Java微信支付-支付成功异步回调验签
接上一篇Java微信支付-统一下单API,本篇在上篇文章的基础上讲述调用统一下单API用户支付成功之后微信异步回调通知 下文中所需配置.类都在以请查看以上链接内容. 在调用微信支付-统一下单API时, ...
最新文章
- thinkphp 使用外部php或html 原理
- 常用的 Java 工具类之 Apache 全家桶使用
- gis影像格式img转为ecw_医学影像图片格式
- promise.all_所有您需要了解的Promise.all
- 渗透测试入门4之内网跨边界应用
- 程序员的职业规划_大学毕业进入职场,程序员如何进行合理的互联网职业规划?...
- AndroidStudio常用字体
- win7快捷关闭计算机,win7关机快捷键和重启快捷键是什么?
- 中医大2020年7月网考计算机应用基础,2020年7月网络教育统考《计算机应用基础》Internet应用模拟题试卷2...
- 10000个小时-------马尔科姆·格拉德威尔
- java代码运行的三个步骤,22年最新
- 印象笔记终于支持 Markdown 了
- 香港证券港股开户解决方案
- 关于vue的视频上传
- linux下解压文件的几种小操作
- 蓝桥杯基础练习之 闰年判断 、 01字串 、查找整数、数列特征 、字母图形
- 概率统计(probability statistics)
- JavaWeb-学生宿舍管理系统
- 升级合作伙伴计划,实现全面赋能
- OpenStack Days China:华云数据CTO郑军分享OpenStack创新实践