前言

项目开发中可能会出现需要多个同步任务串行执行,或者多个异步任务都执行完毕再执行下一步的

其实如果用kotlin的协程的话,可以很方便的完成,但如果不想用kt写或者引入协程库的话,就可以用下面两个工具类

正文

同步串行执行任务,使用链表结构

import com.lt.androidkj.utils.mlistener.EmptyListener
import com.lt.androidkj.utils.mlistener.FunctionFlowBeanListener/*** creator: lt  2019/11/26--10:40    lt.dygzs@qq.com* effect : 方法顺序运作工具类,使用链表数据结构* warning:*/
class FunctionFlow {private var first: LinkedBean? = null//头结点private var last: LinkedBean? = null//尾结点private var finishListener: EmptyListener? = null//全部事件结束的回调/*** 顺序的添加任务* @param id 正常情况下没什么用,但是next(n)的时候跳转到指定的id上* @param function 执行的任务,回调里有个FunctionFlowBean类型的参数,调用他的invoke()可以执行后面的方法*/fun add(id: Int = 0, function: FunctionFlowBeanListener): FunctionFlow {//第一次添加if (first == null) {first = LinkedBean(function, id)last = firstreturn this}//以后再添加val functionFlowBean = LinkedBean(function, id)last!!.next = functionFlowBeanlast = functionFlowBeanreturn this}/*** 开始顺序执行所有任务,后面的任务完成后调用.invoke()即可开始下一个任务* @param finishListener 全部任务完成后触发,可以不传*/@JvmOverloadsfun start(finishListener: EmptyListener? = null) {val first = first ?: returnthis.finishListener = finishListener//设置尾结点,保证链式调用中,参数不为空val noFunctionFlowBean = LinkedBean({}, -1)last!!.next = noFunctionFlowBeanlast = noFunctionFlowBean//开始第一个任务first.function(first.next!!)}/*** 链表bean*/inner class LinkedBean(val function: FunctionFlowBeanListener,val id: Int,var next: LinkedBean? = null) {/*** 开始下一个任务* @param skip -1表示下一个任务,大于0表示跳到id为n的任务*/@JvmOverloadsfun ok(skip: Int = -1) {if (skip < 0) {//执行下一个任务val next = nextif (next == null) {finishListener?.invoke()return}function(next)} else {//跳到id为n的任务var next: LinkedBean? = thiswhile (true) {if (next == null) {//判断如果后续没有方法,则走finishfinishListener?.invoke()return}if (next.id == skip) {//如果下一个任务的id和指定的id相同,则调用下一个方法next.function(next.next!!)return}next = next.next//如果上面两个条件都不符合,则判断下一个任务}}}}
}typealias EmptyListener = () -> Unit
typealias FunctionFlowBeanListener = (FunctionFlow.LinkedBean) -> Unit
typealias FunctionStartsBeanListener = (FunctionStarts.EndBean) -> Unit

使用方式:

异步并行执行任务,也是使用的链表结构:

import com.lt.androidkj.utils.ThreadPool.ThreadType.*
import com.lt.androidkj.utils.mlistener.EmptyListener
import com.lt.androidkj.utils.mlistener.FunctionStartsBeanListener/*** creator: lt  2019/12/23--17:15    lt.dygzs@qq.com* effect : 同时执行所有任务,全部执行完成后调用完成的回调,可以指定线程,默认子线程* warning:*/
class FunctionStarts {private val map = LinkedHashMap<EndBean, ThreadPool.ThreadType>()/*** 添加任务,并指定该任务所运行的线程模式*/fun add(type: ThreadPool.ThreadType = CACHE, function: FunctionStartsBeanListener): FunctionStarts {map[EndBean(function)] = typereturn this}/*** 开始所有任务,并在全部完成后执行回调,且不保证运行在哪个线程中*/fun start(finishListener: EmptyListener) {map.forEach { (bean, type) ->when (type) {SINGLE -> ThreadPool::submitToSingleThreadPoolCACHE -> ThreadPool::submitToCacheThreadPoolFIXED -> ThreadPool::submitToTimeThreadPoolNoTimeMAIN -> ::post}{bean.endListener = {synchronized(this@FunctionStarts) {map.remove(bean)if (map.size == 0)finishListener()}}bean.run(bean)}}}/*** 调用该类的end方法,表示任务已经执行完毕* @param run 提交的任务*/class EndBean(val run: FunctionStartsBeanListener) {//任务结束的回调var endListener: EmptyListener? = null/*** 表示任务已经执行完毕*/fun ok() {endListener?.invoke()}}
}/*** 线程类型*/enum class ThreadType {/*** 单例线程,选择这种方式会按照启动的先后顺序串行执行*/SINGLE,/*** 缓存线程池,选择这种方式会和其他任务并行执行,且无上限*/CACHE,/*** 固定长度的线程池,达到设定的线程数量后,后面的任务等待空闲线程执行完毕后再执行*/FIXED,/*** 跑在主线程中*/MAIN}
::post实现方式如下val handler=Handler()fun post(listener:EmptyListener){handler.post(listener)}其他的submitXXX都是提交到线程池,类似于如下
val singleThreadExecutor = Executors.newSingleThreadExecutor()//可以自己搜索如何创建或自定义线程池fun submitToSingleThreadPool(runnable: EmptyListener): Future<*> =singleThreadExecutor.submit(runnable)

使用方式:

而且还能联合使用来应对复杂需求,比如

先按照顺序弹两个弹窗(关闭前一个在打开下面的),然后请求三个异步接口(但要求第二个和第三个要按顺序执行),接口全部成功后在按照顺序弹两个弹窗

FunctionFlow().add {showSelectPhotoDialog(1) { arr ->it.ok()}}.add {showSelectPhotoDialog(1) { arr ->it.ok()}}.add {//执行异步网络请求FunctionStarts().add {http1 {it.ok()}}.add(ThreadPool.ThreadType.SINGLE) {http2 {it.ok()}}.add(ThreadPool.ThreadType.SINGLE) {http3 {it.ok()}}.start {print("异步接口执行完毕")it.ok()}}.add {showSelectPhotoDialog(1) { arr ->it.ok()}}.add {showSelectPhotoDialog(1) { arr ->it.ok()}}.start {print("任务全部执行完成")}

手动实现kt(java)同步工作流和异步工作流相关推荐

  1. java同步转化成异步_Java 如何把异步调用模拟成同步调用

    在某些时候,须要把异步调用模拟成同步调用的形态.例如,基于基于异步通讯的客户端须要同步调用. :-)异步 要实现这个转换,能够有多种实现方法:this 1.很经常使用的方法,应用循环机制:spa bo ...

  2. java同步接口和异步接口_同步接口和异步接口

    定义 答案:来自网络搜索 同步调用:当一个支付请求被发送到支付渠道方,支付渠道会很快返回一个结果.但是这个结果,只是告诉你调用成功了,不是扣款成功,这叫同步调用; 异步调用:同步请求参数里面会有一个回 ...

  3. java 同步异步_Java中的同步于异步

    java异步同步应用 所谓异步输入输出机制,是指在进行输入输出处理时,不必等到输入输出处理完毕才返回.所以异步的同义语是非阻塞(None Blocking). 网上有很多网友用很通俗的比喻 把同步和异 ...

  4. java 同步和异步

    1.举个例子:普通B/S模式(同步)AJAX技术(异步) 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步: 请求通过事件触发->服务器处理( ...

  5. Java 同步、异步

    1.同步与异步: 同步与异步通常来形容一次方法调用. 同步:方法调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为. 异步:方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者 ...

  6. JAVA发送HTTP同步请求和异步请求

    JAVA发送HTTP同步请求和异步请求 同步请求:每一次执行httpClient.execute方法时都是阻塞的,必须等待到响应才能继续往下走. CloseableHttpClient httpCli ...

  7. java 阻塞与非阻塞_简述JAVA同步、异步、阻塞和非阻塞之间的区别

    同步和异步,阻塞和非阻塞是大家经常会听到的概念,但是它们是从不同维度来描述一件事情,常常很容易混为一谈. 1. 同步和异步 同步和异步描述的是消息通信的机制. 同步 当一个request发送出去以后, ...

  8. java同步异步区别_同步请求和异步请求的区别

    同步请求和异步请求的区别 先解释一下同步和异步的概念 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式. 异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的 ...

  9. java 同步与异步区别_同步和异步有何异同,在什么情况下分别使用它们?

    2015-05-12 06:30:01 阅读( 4 ) 通俗版:举个例子:普通B/S模式(同步)AJAX技术(异步) 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器 ...

最新文章

  1. 无监督学习与有监督学习的本质区别是什么_人工智能中的无监督学习
  2. R语言使用caret包的confusionMatrix函数计算混淆矩阵、使用编写的自定义函数可视化混淆矩阵(confusion matrix)
  3. mysql栏目表设计_MySQL表设计
  4. sql join 与where的区别
  5. excel表格怎么调整行高和列宽_8个实用Excel小技巧,谁用谁说好
  6. FFmpeg中MPEG-4编码程序追踪,其他FFMPEG自带编码器同理
  7. [JavaScript] 正则表达式
  8. 【Python】万花筒
  9. Decorator(装饰器)
  10. 系统架构设计_分布式、服务化的ERP系统架构设计
  11. asp.net后台程序动态加载js或样式表
  12. 图两点间的最短路径,所有路径算法C语言实现
  13. Office 2007打开提示The setup controller has encountered
  14. struts框架的原理和应用_分布式开源调度框架TBSchedule原理与应用
  15. 《数据结构与抽象:Java语言描述(原书第4版)》一Java插曲1
  16. 软件自动化测试—代码覆盖率
  17. Asp .Net core 2 学习笔记(1) —— Starup
  18. win10计算机设备感叹号,win10系统设备管理中摄像头驱动显示黄色感叹号的解决办法...
  19. 前馈神经网络初步了解
  20. 内存管理基础学习笔记 - 4.2 缺页中断处理 - do_page_fault

热门文章

  1. 数据挖掘系列(2)--关联规则FpGrowth算法
  2. 电力系统继电保护原理及仿真_电力系统继电保护(529页)
  3. Python中join()方法和os.path.join()方法
  4. QT中利用Qlabel显示当前的时间:年-月-日-时-分-秒-星期
  5. 第五章 逻辑回归模型在评分卡开发中的应用
  6. 最小二乘法多项式拟合的Java实现--转
  7. 【Python】pymysql基础:数据库操作
  8. The Wide and Deep Learning Model(译文+Tensorlfow源码解析) 原创 2017年11月03日 22:14:47 标签: 深度学习 / 谷歌 / tensorf
  9. 逻辑回归、决策树和支持向量机(I)
  10. 大数据时代医疗行业爆发 政策壁垒仍是最大障碍