<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Future模式(異步獲取結果,自實現) 傳統串行流程如下: ![](https://img.kancloud.cn/08/c5/08c552721f6a4ee954d0101ce5148473_1108x932.png) 在獲取數據時會阻塞等待,拿到數據后再執行其他的任務。 而`Future`模式會立即返回一個憑證(`Future`),這時可以執行其他任務;等需要數據再通過前面的`Future`憑證獲取數據即可,流程如下圖: ![](https://img.kancloud.cn/87/ed/87edd48c6b0b27010dae45577e8d712b_1112x934.png) 如下我們來自己實現一個簡單的Future模式: 首先分析設計如下對象: * Main 系統啟動,調用Client發出請求,得到立即返回的FutureData * Client 客戶端,發出獲取Data的請求,立即返回FutureData,并開啟線程裝配RealData * Data 返回數據的接口 * FutureData 虛擬的數據,是一個憑證,需要裝配RealData * RealData 真實數據,構建較慢 代碼如下: Data接口: ~~~ public interface Data { String getResult() throws InterruptedException; } ~~~ RealData類: ~~~ public class RealData implements Data{ private String content; public RealData(String content){ this.content = content; } @Override public String getResult() { return content; } } ~~~ FutureData類: ~~~ public class FutureData implements Data { // 是否準備好 private boolean isReady; // 組裝真實數據 private RealData realData; @Override public synchronized String getResult() { // 沒有準備好,則阻塞等待 while (!isReady){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return realData.getResult(); } public synchronized void setRealData(RealData realData){ if(isReady){ return; } this.realData = realData; this.isReady = true; // 通知其他線程 notifyAll(); } } ~~~ Client類: ~~~ public class Client { // 請求數據 public FutureData request(String queryStr){ FutureData futureData = new FutureData(); // 開啟線程異步出組裝真實數據 new Thread(()->{ // 耗時操作 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } // 構建真實數據 RealData realData = new RealData("hello future," + queryStr); futureData.setRealData(realData); }).start(); // 立即返回 return futureData; } } ~~~ Main程序類: ~~~ public class Main { public static void main(String[] args) { Client client = new Client(); FutureData futureData = client.request("測試"); // 做其他的事情 System.out.println("做其他事情1"); System.out.println("做其他事情2"); // 獲取結果 String result = futureData.getResult(); System.out.println("異步結果為:"+result); } } ~~~ ``` 輸出結果: 做其他事情1 做其他事情2 異步結果為:hello future,測試 ``` ## JDK中的Future模式 如下圖,是`JDK1.8`中封裝的`Future`模式實現。(1.5就又引入了`Future`模式,1.8的功能更加強大,提供了`CompletableFuture`) ![](https://img.kancloud.cn/d2/f3/d2f360946f93fe85c06b1c3352f33321_1100x1004.png) 其中: * `類MyCallable`實現的`Callable`接口的`call()`方法會返回真實的數據(類似于自實現Future模式中的數據接口`Data`的`getResult()`方法) * FutureTask類似于FutureData,都是用來當做異步調用里的立即返回的憑證 * 線程池類似于Client,都是用來執行任務的 如下是JDK的future的例子: MyCallable類: ~~~ public class MyCallable implements Callable<String> { private String str; public MyCallable(String str){ this.str = str; } @Override public String call() throws Exception { // 模擬比較耗時的操作 Thread.sleep(2000); return "hello jdk future," + str; } } ~~~ Main程序: ~~~ public class Main { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(1); FutureTask<String> futureTask = new FutureTask<>(new MyCallable("測試")); // 提交任務 executor.submit(futureTask); System.out.println("處理其他邏輯1"); System.out.println("處理其他邏輯2"); String result = futureTask.get(); System.out.println("(jdk)異步處理結果為:"+result); executor.shutdown(); } } ~~~ ``` 數據結果: 處理其他邏輯1 處理其他邏輯2 (jdk)異步處理結果為:hello jdk future,測試 ``` 另外,JDK的Future模式的Future接口還提供了一些高級的功能。 ``` boolean cancel(boolean mayInterruptIfRunning);// 取消任務 boolean isCanclled();// 是否已經取消 boolean isDone();// 是否已經完成 V get(long timeout,TimeUnit unit);// 超時時間內獲取結果 ``` ## Guava擴展Future模式 `JDK`的`Future`模式中,`future.get()`是阻塞的,不利于高并發開發。`Guava`增強了`Future`模式,增加了完成時的回調接口,使`future`完成時可以自動通知應用程序進行獲取處理。 對上面的程序改造為guava的設置回調函數的方式,代碼如下: Main程序: ~~~ public class Main { public static void main(String[] args){ ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(4)); // 提交任務 ListenableFuture<String> future = executorService.submit(new MyCallable("測試")); // 添加回調函數 future.addListener(()->{ String result = null; try { result = future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("(guava)異步處理結果為:"+result); },MoreExecutors.directExecutor()); System.out.println("處理其他邏輯1"); System.out.println("處理其他邏輯2"); executorService.shutdown(); } } ~~~ 輸出結果: ``` 處理其他邏輯1 處理其他邏輯2 (guava)異步處理結果為:hello guava future,測試 ``` ## Netty擴展Future模式 netty中也提供了支持設置Future回調的擴展。 ~~~ public class Main { public static void main(String[] args) { // 創建netty線程組 EventExecutorGroup group = new DefaultEventExecutorGroup(4); // 提交任務 Future<String> future = group.submit(new MyCallable("測試")); System.out.println("處理其他邏輯1"); System.out.println("處理其他邏輯2"); future.addListener(new FutureListener<String>(){ @Override public void operationComplete(Future<String> future) throws Exception { String result = future.get(); System.out.println("(netty)異步處理結果為:"+result); } }); group.shutdownGracefully(); } } ~~~ ## JDK8的CompletableFuture `JDK8`中提供的`CompletableFuture`更加強大。 `CompletableFuture`實現了`CompletionStage`接口和`Future`接口,前者是對后者的一個擴展,增加了異步回調、流式處理、多個`Future`組合處理的能力,使`Java`在處理多任務的協同工作時更加順暢便利。 使用`CompletableFuture`改造支持異步回調方法,代碼如下: MySupplier類: ~~~ public class MySupplier implements Supplier<String> { private String str; public MySupplier(String str){ this.str = str; } @Override public String get() { // 模擬比較耗時的操作 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return "hello jdk CompletableFuture," + str; } } ~~~ Main程序: ~~~ public class Main { public static void main(String[] args){ CompletableFuture<String> future = CompletableFuture.supplyAsync(new MySupplier("測試"), Executors.newFixedThreadPool(1)); future.whenCompleteAsync((r,t)->{ System.out.println("(CompletableFuture)異步處理結果為:"+r); }); System.out.println("處理其他邏輯1"); System.out.println("處理其他邏輯2"); } } ~~~ 輸出結果: ``` 處理其他邏輯1 處理其他邏輯2 (CompletableFuture)異步處理結果為:hello jdk CompletableFuture,測試 ``` ## 總結 1. 在`JDK1.5`中提供了`Future`模式,獲取數據時阻塞的,所以其他框架(`guava`和`netty`)對`Future`模式做了擴展,支持了回調函數。 2. 在`JDK1.8`中提供了`CompletableFuture`,支持了更加強大的異步回調、流式處理、多個`Future`組合處理的能力。 ## 參考資料 * 書籍 葛一鳴 * 《Java高并發程序設計》
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看