日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

手动实现kt(java)同步工作流和异步工作流

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手动实现kt(java)同步工作流和异步工作流 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

項目開發中可能會出現需要多個同步任務串行執行,或者多個異步任務都執行完畢再執行下一步的

其實如果用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)同步工作流和异步工作流的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。