日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

在過去的好多年里,多線程和異步一直作為 JAVA 技術里的高級部分,在技術序列中,一個語言分為入門部分、進階部分和高級部分,所以,異步是作為其中的高級技術部分存在的。

關于異步和多線程這部分吧,常常存在于面試題、八股文當中,但是在大多數的項目代碼中你根本看不著它。神奇嗎,就是這么神奇。

糾其原因可能有兩個:

  1. 本身大多數項目就很簡單,根本就用不著多線程和異步,畢竟平庸屬于大多數;
  2. Java 中關于多線程和異步的部分確實對于新手不太友好,涉及到的類且多且亂,而且不符合我們正常的思考方式;

我就見過很多同學,多次想入門多線程和異步,但是多次被勸退,或者在大門口反復橫跳。

一旁的 Node.js 、Go 憋了一眼:哼,不就會異步嗎,有那么難嗎?

在 Java 中實現異步編程有什么方式呢?

異步回調函數

最開始寫前端的時候最常用這種回調函數的方法,在 JavaScript 中,函數是一等公民,用法非常靈活。但是在 Java 中,回調方式并不常用。

在異步調用結束或者發生異常的時候主動的調用回調方法,以此來達到異步通知的目的。首先定義一個回調接口,如下:

public interface ICallBackService {

    /**
     * 回調方法
     * @param args 參數
     */
    void callback(String ...args) throws InterruptedException;
}

然后在你的異步方法中加一個回調參數,參數類型就是上面的 ICallBackService接口類型。

public class Work {

    /**
     * 業務邏輯
     * @param callBackService
     */
    public void doWork(ICallBackService callBackService) throws InterruptedException {
        System.out.println("開始回調");
        callBackService.callback("第一個參數","第二個參數");
        System.out.println("回調結束");
    }
}

之后在調用端調用doWork方法執行異步調用。

public static void mAIn(String[] args) throws InterruptedException {
        System.out.println("準備發起異步調用");
        Thread thread = new Thread(() -> {
            Work work = new Work();
            try {
                work.doWork(new ICallBackService() {
                    @Override
                    public void callback(String... args) throws InterruptedException {
                        Thread.sleep(1000);
                        System.out.printf("正在執行回調動作:%s%n",args==null?"無參數":String.join(",", args));
                    }
                });
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread.start();

        System.out.println("繼續干其他事兒");
    }

執行后,打印的結果,主線程該干什么干什么,異步方法執行后,主動調用回調方法。

準備發起異步調用 繼續干其他事兒 異步執行 正在執行回調動作:第一個參數,第二個參數 回調結束

回調這種機制有個最要命的問題,它會導致代碼邏輯的割裂,本來是一個從開始到結束的完整執行過程,但是回調方法脫離了代碼主流程,導致我們看代碼的時候產生跳躍感。

CompletableFuture 異步

自從 Java 8 出現 Future 之后,異步編程就變得簡單多了,回調函數完全可以不用了。再遇到需要異步的場景時,可以直接祭出 CompletableFuture,CompletableFuture 除了有最基礎的異步調用功能外,還支持異步任務鏈、組合任務等等。

異步編程最繁雜的地方就是流程控制,對于 NodeJS 那種天生就是異步的語言來說,有豐富的第三方框架,而對于 Java 來說,到現在都比較少。

在不借助第三方框架的情況下,CompletableFuture 應該是最優解了。

下面這段代碼展示了異步調用兩個任務,然后將兩個任務的返回結果合并到一起,用到了 CompletableFuture 的組合任務功能。

public static void main(String[] args) throws ExecutionException, InterruptedException {
 //異步發起第一個任務
 CompletableFuture<String> firstTask = CompletableFuture.supplyAsync(() -> {
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     throw new RuntimeException(e);
    }
    return "第一個任務的結果";
   }
 );
 //異步發起第二個任務
 CompletableFuture<String> secondTask = CompletableFuture.supplyAsync(() -> "第二個任務的結果");

 // 合并兩個任務的結果
 CompletableFuture<String> comb.NETask = firstTask.thenCombineAsync(secondTask, (firstResult, secondResult) -> {
  return firstResult + "&&" + secondResult;
 });

 combineTask.thenAccept((result) -> {
  System.out.println("最終結果:" + result);
 });
 System.out.println("其他任務,該干嘛干嘛");

 combineTask.join();
}
}

Reactor 響應式編程

用過 Spring Boot 的同學一定看到過 webFlux 這個東西,其實它就是 Reactor 中的功能。Reactor 的核心包是 reactor-core ,專為異步編程而生,已經是 Spring Boot 的內置框架了。

Reactor 是一個完全非阻塞的JVM響應式編程框架。響應式編程是一種涉及數據流和變化傳播的異步編程范式。這意味著可以通過編程語言輕松地表示靜態(如數組)或動態(如事件發射器)數據流。

事件發射器可以理解為事件驅動,如果做過 GUI 或客戶端開發的肯定對事件驅動非常熟悉,事件驅動其實就是順著人的思考模式來的,進行什么操作就觸發什么事件。

下面是用 Reactor 實現的一個簡單異步任務,其中subscribe 方法可以理解為一個事件訂閱器,在里面可以訂閱 onNext (也就是正常執行)、onError (發生錯誤是執行)以及onComplete(執行完成)等事件。每命中一個事件,就可以驅動這個事件做一些事情。

就是以順序寫代碼的方式,實現異步的邏輯。

public static void main(String[] args) {
 Mono<String> asyncTask = Mono.fromCallable(() -> {
  // 模擬異步操作
  Thread.sleep(1000);
  // 返回結果
  return "任務執行成功";
 });

 // 訂閱事件
 asyncTask.subscribe(
   result -> {
    // onNext 事件,處理任務成功的情況
    System.out.println("任務成功,結果:" + result);
   },
   error -> {
    // onError 事件,處理任務出錯的情況
    System.err.println("任務出錯:" + error.getMessage());
   },
   () -> {
    // onComplete 事件,處理任務完成的情況
    System.out.println("任務完成");
   }
 );

 // 使用 block 方法等待異步任務完成
 String result = asyncTask.block();
 System.out.println("主線程等待結果:" + result);
}

執行以上代碼前,需要引入 reactor-core 依賴包。

<dependency>
  <groupId>io.projectreactor</groupId>
  <artifactId>reactor-core</artifactId>
  <version>3.6.0</version>
</dependency>

與 Reactor 類似的還有 RxJava,在 Android 開發上用的最多。

分享到:
標簽:Java
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定