Java中的異步回調(diào)問題
有時候我們執(zhí)行一個任務(wù)需要很長時間,單線程環(huán)境下 會處于阻塞狀態(tài),嚴(yán)重影響效率,那么可以使用一種非阻塞的處理方式,這就是使用多線程。
多線程情況下,問題出來了,我們不知道線程什么時候執(zhí)行完畢,或者不知道如何處理子線程的結(jié)果
那么就有以下兩種方式:異步回調(diào)和同步等待線程處理結(jié)果兩種方式
1. 異步回調(diào)
直接上代碼,固定格式:主業(yè)務(wù)代碼和一個處理結(jié)果的接口
/** * Callback * 回調(diào)一般是異步處理的一種技術(shù)。 * 一個回調(diào)是被傳遞到并且執(zhí)行完該方法。 這種方式只能異步回調(diào), * 如果需要同步等待線程處理結(jié)果可以使用下面介紹的Futures */ interface MyCallback { void doCallback(Map<String, Object> params); } public class TestAsyncCallBack { static ExecutorService es = Executors.newFixedThreadPool(2); public static void doSomething(MyCallback callback) { // 初始化一個線程 Thread t = new Thread() { public void run() { // 這里是業(yè)務(wù)邏輯處理 System.out.println("子線任務(wù)開始執(zhí)行:" + Thread.currentThread().getId()); // 為了能看出效果 ,讓當(dāng)前線程阻塞5秒 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子線任務(wù)結(jié)束執(zhí)行:"); // 處理完業(yè)務(wù)邏輯, Map<String, Object> params = new HashMap<String, Object>(); params.put("a1", "子線程處理結(jié)果"); callback.doCallback(params); } }; es.execute(t); //一定要調(diào)用這個方法,不然executorService.isTerminated()永遠不為true es.shutdown(); } public static void main(String[] args) { // 內(nèi)部類 等價于 new MyCallBack(){...}, 主要作用就是重寫doCallback方法 doSomething((params) -> { System.out.println("單個線程也已經(jīng)處理完畢了,返回參數(shù)a1=" + params.get("a1")); }); System.out.println("主線任務(wù)已經(jīng)執(zhí)行完了:" + Thread.currentThread().getId()); } }
2. 使用Future同步等待執(zhí)行結(jié)果
主要是利用了Callable接口開啟進行多線程,call方法可以返回結(jié)果
/** * Futures是一個抽象的概念,它表示一個值,該值可能在某一點變得可用。一個Future要么獲得計算完的結(jié)果,要么獲得計算失敗后的異常 * 每傳遞一個Runnable對象到ExecutorService.submit()方法就會得到一個回調(diào)的Future,你能使用它檢測是否執(zhí)行,這種方法可以是同步等待線處理結(jié)果 */ public class TestFuture { public static void main(String[] args) { Callable<Result> callable = new Callable<Result>() { @Override public Result call() throws Exception { //這里是業(yè)務(wù)邏輯處理 //讓當(dāng)前線程阻塞1秒看下效果 Thread.sleep(5000); return new Result("張三"); } }; ExecutorService executorService = Executors.newFixedThreadPool(5); Future<Result> resultFuture = executorService.submit(callable); executorService.shutdown(); /** * 無限循環(huán)等待任務(wù)處理完畢 如果已經(jīng)處理完畢 isDone返回true */ while (!resultFuture.isDone()) { try { Result result = resultFuture.get(); // 在這一步阻塞知直到得到子線程返回結(jié)果 System.out.println(result.getName()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } } class Result { private String name; public Result(String name) { this.name = name; } public String getName() { return name; } }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis+springboot發(fā)布postgresql數(shù)據(jù)的實現(xiàn)
本文主要介紹了mybatis+springboot發(fā)布postgresql數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解
這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03Mybatis Plus條件構(gòu)造器ConditionConstructor用法實例解析
這篇文章主要介紹了Mybatis Plus條件構(gòu)造器ConditionConstructor用法實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08