一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java中線程池最實用的創建與關閉指南

java中線程池最實用的創建與關閉指南

2021-12-24 12:57jacky 鄭 Java教程

試中經常會問到,創建一個線程池需要哪些參數啊,線程池的工作原理啊,卻很少會問到線程池如何安全關閉的,下面這篇文章主要給大家介紹了關于java中線程池最實用的創建與關閉的相關資料,需要的朋友可以參考下

前言

在日常的開發工作當中,線程池往往承載著一個應用中最重要的業務邏輯,因此我們有必要更多地去關注線程池的執行情況,包括異常的處理和分析等。

 

線程池創建

避免使用Executors創建線程池,主要是避免使用其中的默認實現,那么我們可以自己直接調用ThreadPoolExecutor的構造函數來自己創建線程池。在創建的同時,給BlockQueue指定容量就可以了。

private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
      60L, TimeUnit.SECONDS,
      new ArrayBlockingQueue(10));

這種情況下,一旦提交的線程數超過當前可用線程數時,就會拋出java.util.concurrent.RejectedExecutionException,這是因為當前線程池使用的隊列是有邊界隊列,隊列已經滿了便無法繼續處理新的請求。但是異常(Exception)總比發生錯誤(Error)要好。

除了自己定義ThreadPoolExecutor外。還有其他方法。這個時候第一時間就應該想到開源類庫,如apache和guava等。

推薦使用guava提供的ThreadFactoryBuilder來創建線程池。

public class ExecutorsDemo {

  private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
      .setNameFormat("demo-pool-%d").build();

  private static ExecutorService pool = new ThreadPoolExecutor(5, 200,
      0L, TimeUnit.MILLISECONDS,
      new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

  public static void main(String[] args) {

      for (int i = 0; i < Integer.MAX_VALUE; i++) {
          pool.execute(new SubThread());
      }
  }
}


 

只需要執行shutdown就可以優雅關閉

package com.zxd.concurrent;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


  public static void main(String[] args) {
      // TODO 如何正確優雅簡單的關閉線程池 ,無須其他多余操 ;創建線程池我選擇用這種方法比較可靠
      ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
      //接收處理數據的結果集合
      List<Integer> resList = Lists.newArrayList();
      //開啟的任務 我們設置的核心處理線程數5個所以 會有多出來的線程在隊列中等待
      for (int i = 0; i < 30; i++) {
          executor.execute(new Task(i, resList));
      }
      //1、關閉線程池 一定要在循環結束關閉
      //2、這個關閉方法不會立即關閉所有在執行的任務線程,
      executor.shutdown();
      //4.這里是檢查線程池是否所有任務都執行完畢關閉
      int j = 0;
      while (true) {
          //5.這里是等線程池徹底關閉以后做的判斷 保證所有線程池已經全部關閉退出while循環
          if (executor.isTerminated()) {
              System.out.println("所有線程已經運行完畢:" + j);
              break;
          }
          // 為避免一直循環 加個睡眠
          try {
              //如果執行shutdown方法沒有關閉的線程池線程池會嘗試關閉
              System.out.println("嘗試關閉線程次數:" + j);
              j++;
              Thread.sleep(300);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }

      //FIXME 3、下面的方法會立即關閉線程池,沒有執行完的也不會在執行了,如果有等待隊列的任務也不會繼續執行
      System.out.println("【完成的總線程數】:" + resList.size());

  }

  static class Task implements Runnable {
      int name;

      List<Integer> list;

      public Task(int name, List<Integer> list) {
          this.name = name;
          this.list = list;
      }

      @Override
      public void run() {
          for (int i = 1; i <= 10; i++) {
              int j = i * 10;
              // 做業務處理
              //System.out.println("task " + name + " is running");
          }
          list.add(name + 1);
          System.out.println("task " + name + " is over");
      }
  }

}

輸出結果

task 0 is over
task 3 is over
task 1 is over
task 2 is over
task 7 is over
task 6 is over
task 5 is over
嘗試關閉線程次數:0
task 10 is over
task 9 is over
task 4 is over
task 8 is over
task 14 is over
task 13 is over
task 12 is over
task 11 is over
task 18 is over
task 17 is over
task 16 is over
task 15 is over
task 22 is over
task 21 is over
task 20 is over
task 19 is over
task 26 is over
task 25 is over
task 24 is over
task 23 is over
task 29 is over
task 28 is over
task 27 is over
所有線程已經運行完畢:1
【完成的總線程數】:30

 

執行shutdownNow關閉的測試

package com.zxd.concurrent;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


  public static void main(String[] args) {
      // TODO 如何正確優雅簡單的關閉線程池 ,無須其他多余操 ;創建線程池我選擇用這種方法比較可靠
      ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
      //接收處理數據的結果集合
      List<Integer> resList = Lists.newArrayList();
      //開啟的任務 我們設置的核心處理線程數5個所以 會有多出來的線程在隊列中等待
      for (int i = 0; i < 200; i++) {
          executor.execute(new Task(i, resList));
      }
      //1、關閉線程池 一定要在循環結束關閉
      //2、這個關閉方法不會立即關閉所有在執行的任務線程,
//        executor.shutdown();
      //FIXME 3、下面的方法會立即關閉線程池,沒有執行完的也不會在執行了,如果有等待隊列的任務也不會繼續執行
      List<Runnable> list = executor.shutdownNow();
      System.out.println("c剩余的沒有執行的任務【線程數】= " + list.size());
      System.out.println("【完成的總線程數】:" + resList.size());
      //4.這里是檢查線程池是否所有任務都執行完畢關閉
      int j = 0;
      while (true) {
          //5.這里是等線程池徹底關閉以后做的判斷 保證所有線程池已經全部關閉退出while循環
          if (executor.isTerminated()) {
              System.out.println("所有線程已經運行完畢:" + j);
              break;
          }
          // 為避免一直循環 加個睡眠
          try {
              //如果執行shutdown方法沒有關閉的線程池線程池會嘗試關閉
              System.out.println("嘗試關閉線程次數:" + j);
              j++;
              Thread.sleep(300);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }

  }

  static class Task implements Runnable {
      int name;

      List<Integer> list;

      public Task(int name, List<Integer> list) {
          this.name = name;
          this.list = list;
      }

      @Override
      public void run() {
          for (int i = 1; i <= 10; i++) {
              int j = i * 10;
              // 做業務處理
              //System.out.println("task " + name + " is running");
          }
          list.add(name + 1);
          System.out.println("task " + name + " is over");
      }
  }

}

輸出結果

java中線程池最實用的創建與關閉指南

 

總結

到此這篇關于java中線程池最實用的創建與關閉的文章就介紹到這了,更多相關java線程池創建與關閉內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_43450799/article/details/120172437

延伸 · 閱讀

精彩推薦
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
主站蜘蛛池模板: 波多野结衣同性系列698 | 强插美女 | 成人免费视频一区二区 | 免费特黄一区二区三区视频一 | 91porny丨首页 | 亚洲精品乱码久久久久久蜜桃 | 国产一区二区免费在线 | 好紧好爽范冰冰系列 | 天天夜夜草草久久伊人天堂 | 日本视频免费在线 | 亚洲欧美成人中文在线网站 | 我年轻漂亮的继坶2中字在线播放 | 色小孩导航 | 青青青青青国产免费手机看视频 | 天天做天天爽 | 色悠久久久久综合网小说 | 日本公与妇中文在线 | 日韩hd高清xxxⅹ | 亚洲女同在线观看 | 亚洲国产精品成人午夜在线观看 | 国产亚洲精品一区久久 | 青青热久免费精品视频网站 | 好爽好紧小雪别夹小说 | 国产精品一级香蕉一区 | 久久久无码精品亚洲A片猫咪 | 五月天91| 小兰被扒开内裤露出p | 国内交换一区二区三区 | 99久久久久国产 | 欧美性xxxxx 欧美性bbbbbxxxxxddd | 96av视频在线观看 | 免费看a片毛片 | 国产玖玖在线 | 久久囯产精品777蜜桃传媒 | 国产精品国语自产拍在线观看 | 99久久www免费 | 国产日本久久久久久久久婷婷 | 女女同性做爰xxoo亲吻 | 婷婷久久综合九色综合九七 | 国产一区二区三区在线看 | 日本免费看 |