亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java通過Callable和Future來接收線程池的執行結果

發布時間:2020-09-16 22:41:59 來源:腳本之家 閱讀:391 作者:逍遙侯爵 欄目:編程語言

在Java的線程執行中,不管是直接繼承Thread的方式,還是實現Runnable接口的方式,都不會獲取到線程執行的返回結果。這樣如果線程在執行過程中出現了錯誤,那么主線程也不會感知到。即使打印了日志,也不能立即拋出異常。事后查看日志才能發現出現了bug。而且到那時發生問題的代碼點距離真正的問題點可能會相差很遠。如果在線程池執行的過程中出現了bug能及時地拋出異常,那么這將會是一個很好的實現。解決上述問題的辦法是使用Callable接口,其可以獲取到線程的返回結果,通過Future的get方法來承接。以下通過一個1000個線程實現累加的例子,來演示Callable和Future的使用:

package com.hys.test;
 
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
 
import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
public class Test {
 
  private static AtomicInteger num = new AtomicInteger();
 
  public static void main(String[] args) throws InterruptedException, ExecutionException {
    CountDownLatch latch = new CountDownLatch(1000);
    ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("increment-pool-%d").build();
    ExecutorService poolexecutor = new ThreadPoolExecutor(1000, 1000, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    Future<String> submit = null;
    for (int i = 0; i < 1000; i++) {
      if (submit != null && submit.get() != null) {
        latch.countDown();
        continue;
      }
      submit = poolexecutor.submit(() -> {
        try {
          //這里模擬一個耗時很長的操作
          num.getAndIncrement();
          //int a = 1 / 0;
          Thread.sleep(1);
          return null;
        } catch (Exception e) {
          return e.toString();
        } finally {
          latch.countDown();
        }
      });
    }
    poolexecutor.shutdown();
    //主線程等待所有分線程執行完畢后再執行
    latch.await();
    String errorMsg = submit.get();
    //如果子線程在執行過程中有錯誤,則在此拋出該異常
    if (errorMsg != null) {
      throw new RuntimeException(errorMsg);
    }
    System.out.println(num);
  }
}

如果每個線程在執行的過程中沒出現問題,則返回的結果為null。如果返回結果不為null,則代表該線程執行的代碼有問題,此時將錯誤信息返回。放開上述第33行代碼的注釋,以此來模擬一個算術異常,再次執行上述代碼,可以得到如下的結果:

Exception in thread "main" java.lang.RuntimeException: java.lang.ArithmeticException: / by zero
 at com.hys.test.Test.main(Test.java:49)

由上可以看到,在主線程拋出了算術異常,可以被感知到。

但是需要注意的一點的是,如果線程的執行結果互相依賴的話,也就是各線程都會調用Future的get方法的話,get方法不得不等待任務執行完成,換言之,如果多個任務提交后,返回的多個Future逐一調用get方法時,將會依次阻塞,任務的執行從并行變為串行。如果想解決該問題,可以考慮使用Java 8中的CompletableFuture來實現。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

达日县| 濮阳市| 五峰| 阳泉市| 盖州市| 河津市| 东港市| 丽江市| 安陆市| 通州区| 确山县| 内丘县| 浦县| 灵武市| 兰西县| 巴楚县| 孟连| 霍州市| 鹿邑县| 炎陵县| 彭州市| 巫山县| 奉节县| 延津县| 钟山县| 绩溪县| 松原市| 伊吾县| 临潭县| 沙洋县| 北安市| 周至县| 岳阳市| 图片| 大渡口区| 伊春市| 甘谷县| 瓦房店市| 广南县| 句容市| 周口市|