<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      「Java工具類」java線程池工具類,自定義線程池工具類

      介紹語

      本博客主要是Java常用關鍵技術點,通用工具類的分享;以及springboot+springcloud+Mybatisplus+druid+mysql+redis+swagger+maven+docker等集成框架的技術分享;datax、kafka、flink等大數據處理框架的技術分享。文章會不斷更新,歡迎碼友關注點贊收藏轉發!

      關注多的話,后面會錄制一些視頻教程,圖文和視頻結合,比如:圖書介紹網站系統、搶購系統、大數據中臺系統等。技術才是程序猿的最愛,碼友們沖啊

      正文:

      java核心之一就是線程,而用線程池執行線程是好的方式。下面是我封裝的一個線程池工具類,簡單實用。歡迎收藏備用!

      • 為什么需要一個線程池工具類?

      答:整個項目,用到線程執行任務的地方很多,不可能哪里用到就在那里直接new一個線程執行,這樣資源得不到重復利用,一旦線程過多就會導致內存不足。

      • 線程池的好處是什么?

      使用線程池執行線程任務,當一個線程執行完成一個任務之后,線程資源回到線程池,資源得到重復利用。

      • 線程池為什么使用自定義方式?

      阿里文檔推薦使用自定義線程池,因為java自帶線程池都會有可能造成內存不足的問題。自定義線程池,根據服務器配置定制線程池核心線程、最大線程等,是最好的方式。

      • 我封裝的線程池工具類有什么好處?

      使用線程安全的方式定義,整個項目不會重復創建線程池。線程池根據服務器cpu核數創建合適的核心線程數和最大線程數,達到不少創建不多創建剛剛好的配置。使用靜態方法調用,隨處可用,零難度上手。可以執行無返回值線程任務,可以執行有返回值的線程任務。

      工具類

      import com.google.common.util.concurrent.ThreadFactoryBuilder;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import java.util.concurrent.*;
      
      /**
       * 自定義線程創建工具類,創建線程池后不需要關閉
       *
       * @author liangxn
       */
      public class ThreadPoolUtils {
          private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolUtils.class);
          private static ThreadPoolExecutor threadPool = null;
          private static final String POOL_NAME = "myPool";
          // 等待隊列長度
          private static final int BLOCKING_QUEUE_LENGTH = 1000;
          // 閑置線程存活時間
          private static final int KEEP_ALIVE_TIME = 60 * 1000;
      
          private ThreadPoolUtils() {
              throw new IllegalStateException("utility class");
          }
      
      
          /**
           * 無返回值直接執行
           *
           * @param runnable 需要運行的任務
           */
          public static void execute(Runnable runnable) {
              getThreadPool().execute(runnable);
          }
      
          /**
           * 有返回值執行
           * 主線程中使用Future.get()獲取返回值時,會阻塞主線程,直到任務執行完畢
           *
           * @param callable 需要運行的任務
           */
          public static <T> Future<T> submit(Callable<T> callable) {
              return getThreadPool().submit(callable);
          }
      
          private static synchronized ThreadPoolExecutor getThreadPool() {
              if (threadPool == null) {
                  // 獲取處理器數量
                  int cpuNum = Runtime.getRuntime().availableProcessors();
                  // 根據cpu數量,計算出合理的線程并發數
                  int maximumPoolSize = cpuNum * 2 + 1;
                  // 核心線程數、最大線程數、閑置線程存活時間、時間單位、線程隊列、線程工廠、當前線程數已經超過最大線程數時的異常處理策略
                  threadPool = new ThreadPoolExecutor(maximumPoolSize - 1,
                          maximumPoolSize,
                          KEEP_ALIVE_TIME,
                          TimeUnit.MILLISECONDS,
                          new LinkedBlockingDeque<>(BLOCKING_QUEUE_LENGTH),
                          new ThreadFactoryBuilder().setNameFormat(POOL_NAME + "-%d").build(),
                          new ThreadPoolExecutor.AbortPolicy() {
                              @Override
                              public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                                  LOGGER.warn("線程爆炸了,當前運行線程總數:{},活動線程數:{}。等待隊列已滿,等待運行任務數:{}",
                                          e.getPoolSize(),
                                          e.getActiveCount(),
                                          e.getQueue().size());
                              }
                          });
      
              }
      
              return threadPool;
          }
      }

      例子1:

       Future<String> future = ThreadPoolUtils.submit(() -> {
           return "我有返回值哦";
       });
       try {
           logger.info(future.get());
       } catch (InterruptedException | ExecutionException e) {
           logger.error("任務超過指定時間未返回值,線程超時退出");
       }
       ?
       // 控制臺打印日志:
       21:04:19.428 [main] INFO  - 我有返回值哦

      例子2:

      Future<String> futureTimeout = ThreadPoolUtils.submit(() -> {
           Thread.sleep(99999999);
           return "我有返回值,但是超時了";
       });
       try {
           // 建議使用該方式執行任務,不會導致線程因為某寫原因一直占用線程,
           // 從而導致未知問題
           // 注意使用局部try避免主線程異常,導致主線程無法繼續執行
           logger.info(futureTimeout.get(3, TimeUnit.SECONDS));
       } catch (InterruptedException | ExecutionException e) {
           logger.error("任務執行異常");
       } catch (TimeoutException e) {
           logger.error("任務超過指定時間未返回值,線程超時退出");
       }
       ?
       // 控制臺打印日志:
       21:07:24.940 [main] ERROR - 任務超過指定時間未返回值,線程超時退出

      例子3:

      int loop = 40;
       for (int i = 0; i < loop; i++) {
           logger.info("任務{}", i);
           ThreadPoolUtils.execute(() -> {
               logger.info("干活好累");
               try {
                   Thread.sleep(10);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               logger.info("終于干完了");
           });
       }
       logger.info("我在這兒等著你回來等你回來");
       ?
       // 控制臺打印:
       21:08:08.494 [main] INFO  - 任務0
       ............
       21:08:08.540 [main] INFO  - 任務5
       21:08:08.541 [main] INFO  - 任務6
       21:08:08.540 [myPool-4] INFO  - 干活好累
       21:08:08.540 [myPool-1] INFO  - 干活好累
       21:08:08.540 [myPool-3] INFO  - 干活好累
       ............
       21:08:08.543 [main] INFO  - 任務21
       21:08:08.548 [main] INFO  - 任務22
       21:08:08.548 [main] INFO  - 任務23
       21:08:08.548 [myPool-21] INFO  - 干活好累
       21:08:08.549 [main] INFO  - 任務24
       21:08:08.549 [myPool-22] INFO  - 干活好累
       21:08:08.549 [main] INFO  - 任務25
       21:08:08.549 [myPool-23] INFO  - 干活好累
       21:08:08.549 [main] INFO  - 任務26
       ............
       21:08:08.551 [myPool-1] INFO  - 干活好累
       21:08:08.551 [myPool-6] INFO  - 終于干完了
       21:08:08.551 [myPool-7] INFO  - 終于干完了
       21:08:08.551 [myPool-5] INFO  - 干活好累
       21:08:08.551 [main] INFO  - 任務35
       21:08:08.551 [main] INFO  - 任務36
       21:08:08.551 [main] INFO  - 任務37
       21:08:08.551 [main] INFO  - 任務38
       21:08:08.551 [main] INFO  - 任務39
       21:08:08.551 [main] INFO  - 我在這兒等著你回來等你回來
       21:08:08.551 [myPool-2] INFO  - 干活好累
       21:08:08.551 [myPool-3] INFO  - 干活好累
       21:08:08.551 [myPool-8] INFO  - 干活好累
       21:08:08.551 [myPool-6] INFO  - 干活好累
       21:08:08.551 [myPool-7] INFO  - 干活好累
       21:08:08.552 [myPool-13] INFO  - 終于干完了
       21:08:08.552 [myPool-12] INFO  - 終于干完了
       ............
           
       21:08:08.561 [myPool-7] INFO  - 終于干完了
       21:08:08.561 [myPool-3] INFO  - 終于干完了

      例子4:

       // 測試10個線程使用工具類
       ExecutorService executorService = Executors.newFixedThreadPool(10);
       for (int i = 0; i < 10; i++) {
           executorService.submit(new Runnable() {
               @Override
               public void run() {
                   final String name = Thread.currentThread().getName();
                   ThreadPoolUtils.execute(() -> {
                       logger.info("[{}],干活好累", name);
                       try {
                           Thread.sleep(100);
                       } catch (InterruptedException e) {
                           e.printStackTrace();
                       }
                       logger.info("[{}],終于干完了", name);
                   });
               }
           });
       }
       logger.info("不用等他,我們先干");
      
       // 控制臺打印:
       21:11:49.946 [main] INFO  - 不用等他,我們先干
       21:11:49.991 [myPool-4] INFO  - [pool-2-thread-7],干活好累
       21:11:49.991 [myPool-3] INFO  - [pool-2-thread-2],干活好累
       21:11:49.991 [myPool-5] INFO  - [pool-2-thread-5],干活好累
       21:11:49.991 [myPool-8] INFO  - [pool-2-thread-6],干活好累
       21:11:49.991 [myPool-1] INFO  - [pool-2-thread-3],干活好累
       21:11:49.991 [myPool-2] INFO  - [pool-2-thread-9],干活好累
       21:11:49.991 [myPool-9] INFO  - [pool-2-thread-10],干活好累
       21:11:49.991 [myPool-7] INFO  - [pool-2-thread-1],干活好累
       21:11:49.991 [myPool-6] INFO  - [pool-2-thread-4],干活好累
       21:11:49.991 [myPool-0] INFO  - [pool-2-thread-8],干活好累
       21:11:50.091 [myPool-7] INFO  - [pool-2-thread-1],終于干完了
       21:11:50.091 [myPool-4] INFO  - [pool-2-thread-7],終于干完了
       21:11:50.091 [myPool-5] INFO  - [pool-2-thread-5],終于干完了
       21:11:50.091 [myPool-2] INFO  - [pool-2-thread-9],終于干完了
       21:11:50.091 [myPool-0] INFO  - [pool-2-thread-8],終于干完了
       21:11:50.091 [myPool-1] INFO  - [pool-2-thread-3],終于干完了
       21:11:50.091 [myPool-8] INFO  - [pool-2-thread-6],終于干完了
       21:11:50.091 [myPool-6] INFO  - [pool-2-thread-4],終于干完了
       21:11:50.091 [myPool-3] INFO  - [pool-2-thread-2],終于干完了
       21:11:50.091 [myPool-9] INFO  - [pool-2-thread-10],終于干完了
      例子5:
       int loop = 2000;
       for (int i = 0; i < loop; i++) {
           ThreadPoolUtils.execute(() -> {
               logger.info("干活好累");
               try {
                   Thread.sleep(10);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               logger.info("終于干完了");
           });
       }
       logger.info("不用等他,我們先干");
       ?
       // 控制臺打印:
       ............
       21:13:25.083 [myPool-19] INFO  - 干活好累
       21:13:25.083 [myPool-8] INFO  - 干活好累
       21:13:25.083 [myPool-30] INFO  - 干活好累
       21:13:25.085 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.085 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.085 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.085 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.106 [myPool-7] INFO  - 干活好累
       21:13:25.106 [myPool-11] INFO  - 干活好累
       21:13:25.106 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.106 [myPool-6] INFO  - 干活好累
       21:13:25.106 [myPool-4] INFO  - 干活好累
       21:13:25.106 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       21:13:25.106 [main] WARN  - 線程爆炸了,當前運行線程總數:33,活動線程數:33。等待隊列已滿,等待運行任務數:1000
       ............

      鄙人編碼十年多,在項目中也積累了一些工具類,很多工具類在每個項目都有在用,很實用。大部分是鄙人封裝的,有些工具類是同事封裝的,有些工具類已經不記得是ctrl+c的還是自己封裝的了,現在有空就會總結項目中大部分的工具類,分享給各位碼友。如果文章中涉及的代碼有侵權行為請通知鄙人處理。

      計劃是先把工具類整理出來,正所謂工欲善其事,必先利其器。項目中不管是普通單體項目還是多模塊maven項目或是分布式微服務,一部分功能模塊都是可以重用的,工具類模塊就是其中之一。

      posted @ 2021-10-28 22:27  Java夜未眠  閱讀(648)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 天堂av在线一区二区| 岱山县| 亚洲蜜臀av乱码久久| 日韩中文字幕人妻一区| 亚洲欧洲日韩精品在线| 日本一卡2卡3卡4卡无卡免费| 久久综合色之久久综合色| 无码无需播放器av网站| 狠狠亚洲色一日本高清色| 极品人妻少妇一区二区| 精品伊人久久久香线蕉| 疯狂做受xxxx高潮欧美日本| 东京热人妻无码一区二区av| 久久夜色撩人精品国产av| 全球成人中文在线| 2019国产精品青青草原| 国产精品欧美福利久久| 久久不卡精品| 国产精品不卡区一区二| 国产成人综合亚洲第一区| 亚洲成人一区| 日本免费人成视频在线观看| 大屁股国产白浆一二区| 免费看视频的网站| 欧美成人午夜在线观看视频| 欧美 日韩 国产 成人 在线观看| 金湖县| 亚洲无线观看国产精品| 韩国三级+mp4| av区无码字幕中文色| 久久精产国品一二三产品| 国产中文字幕在线精品| 亚洲精品美女一区二区| 大地资源中文第二页日本| 欧美最猛黑人xxxx| 无码视频一区二区三区| 中文字幕在线精品国产| 亚洲另类无码一区二区三区 | 中文字幕亚洲人妻系列| 欧美黑人大战白嫩在线| 成人无码视频97免费|