【JAVA中級篇】線程池

上一篇文章已經介紹了線程的基本概念以及線程相關的API,下面來看一下線程池

一、線程池框架

1、線程池的優點

  1. 重用線程池中的線程,避免因為線程的創建和銷毀所帶來的性能開銷。?
  2. 能有效控制線程池的最大并發數,避免大量線程之間因互相搶奪系統資源而導致的阻塞現象。?
  3. 能夠對線程進行簡單的管理,并提供定時執行以及指向間隔循環執行等功能。

2、JAVA中相關類

Executor是一個頂層接口,它里面只聲明了一個方法execute(Runnable)

ExecutorService接口繼承了Executor接口,并且聲明了一些方法:submit、invokeAll、invokeAny以及shutDown等AbstractExecutorService實現了ExecutorService接口,基本實現了ExecutorService中聲明的所有方法

ThreadPoolExecutor接口繼承了AbstractExecutorService這個類,并且實現了這些重要方法:execute()?、shutdown()、shutdownNow()

Executors提供了大量的static方法,來創建各種特性的線程池(基于ThreadPoolExecutor的構造方法)、大量的callable方法和創建ThreadFactory的方法

ThreadPoolExecutor的重要屬性

    private final BlockingQueue<Runnable> workQueue;//任務緩存隊列,用來存放等待執行的任務private final ReentrantLock mainLock = new ReentrantLock();//線程池的主要狀態鎖,對線程池狀態(比如線程池大小、runState等)的改變都要使用這個鎖private final HashSet<Worker> workers = new HashSet<Worker>();//用來存放工作集private final Condition termination = mainLock.newCondition();//private int largestPoolSize;//用來記錄線程池中曾經出現過的最大線程數private long completedTaskCount;//用來記錄已經執行完畢的任務個數private volatile ThreadFactory threadFactory;//線程工廠,用來創建線程private volatile RejectedExecutionHandler handler;//任務拒絕策略private volatile long keepAliveTime;//線程存活時間 private volatile boolean allowCoreThreadTimeOut;//是否允許為核心線程設置存活時間private volatile int corePoolSize;//核心池的大小(即線程池中的線程數目大于這個參數時,提交的任務會被放進任務緩存隊列)private volatile int maximumPoolSize;//線程池最大能容忍的線程數private static final RejectedExecutionHandler defaultHandler =new AbortPolicy();//默認的任務拒絕策略private static final RuntimePermission shutdownPerm =new RuntimePermission("modifyThread");

這里要重點解釋一下corePoolSize、maximumPoolSize、largestPoolSize三個變量。

corePoolSize在很多地方被翻譯成核心池大小,其實我的理解這個就是線程池的大小。舉個簡單的例子:

  假如有一個工廠,工廠里面有10個工人,每個工人同時只能做一件任務。

  因此只要當10個工人中有工人是空閑的,來了任務就分配給空閑的工人做;

  當10個工人都有任務在做時,如果還來了任務,就把任務進行排隊等待;

  如果說新任務數目增長的速度遠遠大于工人做任務的速度,那么此時工廠主管可能會想補救措施,比如重新招4個臨時工人進來;

  然后就將任務也分配給這4個臨時工人做;

  如果說著14個工人做任務的速度還是不夠,此時工廠主管可能就要考慮不再接收新的任務或者拋棄前面的一些任務了。

  當這14個工人當中有人空閑時,而新任務增長的速度又比較緩慢,工廠主管可能就考慮辭掉4個臨時工了,只保持原來的10個工人,畢竟請額外的工人是要花錢的。

  這個例子中的corePoolSize就是10,而maximumPoolSize就是14(10+4)。

  也就是說corePoolSize就是線程池大小,maximumPoolSize在我看來是線程池的一種補救措施,即任務量突然過大時的一種補救措施。

  不過為了方便理解,在本文后面還是將corePoolSize翻譯成核心池大小。

  largestPoolSize只是一個用來起記錄作用的變量,用來記錄線程池中曾經有過的最大線程數目,跟線程池的容量沒有任何關系。

重要方法

execute

    public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))reject(command);}

3、線程池的分類

newFixedThreadPool

newWorkStealingPool

newSingleThreadExecutor

newCachedThreadPool

newSingleThreadScheduledExecutor

newScheduledThreadPool

重點是ThreadPoolExecutor的代碼、還需要理解線程池狀態、任務的執行、線程池中的線程初始化、任務緩存隊列及排隊策略、任務拒絕策略、線程池的關閉、線程池容量的動態調整

簡單使用Demo

package com.demo;import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPool {   private int threadCount = 10;private int threadpoolCount = 3;public static void main(String[] args) {new ThreadPool().threadPoolControl();}public void threadPoolControl() {       ThreadObject[] et = new ThreadObject[threadCount];       ExecutorService service = Executors.newFixedThreadPool(threadpoolCount);Collection<ThreadObject> c = new ArrayList<ThreadObject>();for (int i = 0; i < threadCount; i++) {   et[i] = new ThreadObject();           c.add(et[i]);}try {service.invokeAll(c);service.shutdown();} catch (InterruptedException e) {e.printStackTrace();}}class ThreadObject implements Callable<Object>{       public Object call() throws Exception {System.out.println("當前線程:"+Thread.currentThread().getName()+",線程對象:"+this);return null;}}
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530368.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530368.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530368.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kafka 腳本發送_Kafka筆記歸納(第五部分:一致性保證,消息重復消費場景及解決方式)...

寫在開頭&#xff1a;本章是Kafka學習歸納第五部分&#xff0c;著重于強調Kafka的事一致性保證&#xff0c;消息重復消費場景及解決方式&#xff0c;記錄偏移量的主題&#xff0c;延時隊列的知識點。文章內容輸出來源&#xff1a;拉勾教育大數據高薪訓練營。一致性保證水位標記…

【Java基礎篇】集合排序

所謂集合排序是指對集合內的元素進行排序。 集合工具類Collections中提供了兩種排序算法&#xff0c;分別是&#xff1a; Collections.sort(List list)Collections.sort(List list,Comparator c) Collections.sort(List list)這種方式需要對象實現Comparable接口&#xff0c;…

語言nomogram校準曲線圖_預測模型的概率校準

1.背景 機器學習分為:監督學習,無監督學習,半監督學習(也可以用hinton所說的強化學習)等。在這里,先簡要介紹一下監督學習從給定的訓練數據集中學習出一個函數(模型參數),當新的數據到來時,可以根據這個函數預測結果。監督學習的訓練集要求包括輸入輸出,也可以說是特征和…

eclipse debug 工程源碼時出現source not found問題解決

問題描述&#xff1a;使用eclipse debug啟動應用&#xff0c;并且打斷點在工程的源碼上面&#xff0c;提示source not found。 問題解決&#xff1a; 1、選中工程&#xff0c;右鍵Debug As》Debug Configurations 2、在Java Application下面選中需要debug的程序&#xff0c;然…

代碼中有個get是啥意思_是時候秀一波了,甩掉get和set,Lombok讓代碼更簡潔

前言前幾天有個新來的同事(實習生)驚訝的對我說&#xff1a;我們的代碼里好多錯誤&#xff0c;我的程序本地都啟動不了。我一臉懵逼的質問他&#xff1a;目前線上的代碼&#xff0c;怎么會有問題嗎&#xff1f;他不服氣的說&#xff1a;你來看嘛&#xff0c;就是有問題&#xf…

JavaWeb工程師知識圖譜

一個工作快三年的的Java菜鳥&#xff0c;總結梳理了一下JavaWeb工程師必須掌握的一些知識點&#xff08;持續更新中。。。&#xff09;。 預覽效果 xmind原始文件 百度云盤 鏈接&#xff1a;https://pan.baidu.com/s/1hp3MWGOX2I8APw75Suu52Q 提取碼&#xff1a;j6w6

【Java中級篇】基于jxl讀寫Excel文件遇到的問題

發生異常&#xff0c;并且提示&#xff1a;unable to recognize ole stream 遇到這個問題需要將Excel文件另存為Excel 97-2003&#xff08;*.xls&#xff09;

松下a6伺服x4接線圖_2021中山東鳳松下溫控器回收價高同行

2021中山東鳳松下溫控器回收價高同行西門子TDC&#xff0c;西門子存儲卡,西門子變頻器等全線西門子自動化產品。小汪 滿意的價格&#xff0c;快的付款速度&#xff0c;熱誠歡迎全國各地朋友洽談合作。具體回收業務&#xff1a;SIEMENS可編程控制器 1、SIMATIC&#xff0c;S7系列…

eclipse啟動發生Failed to load JNI shared library

今天啟動eclipse發生下面的情況 從網上知道是eclipse和jdk位數不一致導致的。 輸入java -version ,查看JDK是多少位&#xff0c;顯示64位的就是64位JDK&#xff0c;未顯示的為32位的JDK。 eclipse的安裝目錄下有一個叫eclipse.ini的配置文件&#xff0c;打開后能看到 x86_64說…

imx226_相機選型器

-- 全部 --AR1820HS (8)CMV2000-2E5C1PP (2)CMV2000-3E12M1PP (2)CMV2000-3E5M1PP (2)CMV4000-3E12M1PP (1)CMV4000-3E5C1PP (5)CMV4000-3E5M1PP (5)EV76C560ABT (25)EV76C560ACT (25)EV76C570ABT (23)EV76C570ACT (23)EV76C661ABT (20)IMX174LLJ-C (8)IMX174LQJ-C (8)IMX178LL…

算法的時間復雜度和空間復雜度的原理

一、算法分析 如何判斷一個算法的好壞呢&#xff1f;首先算法必須要正確&#xff0c;這是最基本的要求。其次&#xff1a; 算法花費的時間算法占用的空間小&#xff08;輔助存儲空間&#xff09;算法要容易調試&#xff0c;測試&#xff0c;理解&#xff0c;編碼&#xff0c;…

5條件篩選功能_一分鐘,徹底學會Excel高級篩選,坐等升職加薪!

Excel中高級篩選是普通篩選的加強&#xff0c;能夠實現更加復雜的篩選功能。請您看下面的示例圖&#xff1a;數據示例圖如果要求篩選出班級為2班且語文成績大于100分的數據&#xff0c;那么使用普通篩選連續篩選兩次就可以得到結果。請您看下面的操作演示&#xff1a;普通篩選操…

數據結構之樹【完善中】

一、樹的概念 樹是一種分組的層次結構。 樹的定義&#xff1a; 樹是n(n>0)個數據元素的集合,在任意一棵非空樹中&#xff0c;有如下特征 有且只有一個根結點&#xff08;無前驅結點&#xff09;當n>1時&#xff0c;其他結點被分為若干個互不相交集合&#xff0c;并且…

phpgif圖片包_PHP生成GIF動態圖片驗證碼

1 <?php2 /**3 * 調用示例4 **/5 session_start();6 $randCode ;7 //驗證碼隨機8 $str"abcdefghjkmnpqrstuvwsyzABCDEFGHJKMNPQRSTUVWSYZ23456789";9 for($i0;$i<4;$i){10 $safe.substr($str,rand(0,strlen($str)),1);11 }12 $_SESSION["imgcode"]…

工程圖標注粗糙度_Inventor教程之工程圖標注實例

1工程圖標注實例對以下實體零件進行全部的標注演示。操作步驟如下&#xff1a;(1)打開文件。運行Inventor&#xff0c;單擊“快速入門”選項卡“啟動”面板上的“打開”按鈕&#xff0c;在“打開”對話框中選擇“實體零件”&#xff0c;單擊“打開”按鈕進入實體零件。(2)新建工…

Oracle數據庫 invalid character問題解決

今天使用PL/SQL Developer這個工具來操作Oracle數據時發現了一個問題&#xff1a; select * from tb_student_grade pivot(max(grade) for course in(math as 數學,chinese as 語文,english as 英語)); 執行這個SQL語句提示invalid character,原因是我的數據庫編碼是AMERICAN…

定時線程_SpringBoot定時任務,@Async多線程異步執行

一、使用SpringBoot實現定時任務這個不是重點&#xff0c;就簡單的實現一下&#xff0c;至于cron表達式怎么寫也不是重點&#xff0c;自行百度即可。1-1、基于 Scheduled 注解的方式import org.springframework.scheduling.annotation.EnableScheduling;import org.springframe…

SpringBoot入門一

SpringBoot能夠很簡單的創建一個直接運行的單體Spring應用 特性&#xff1a; 單體Spring應用內置的tomcat、Jetty提供默認的starter來構建配置自動配置Spring和第三方庫 推薦一個很好的學習教程&#xff0c;https://blog.csdn.net/u010486495/article/details/79348302 1 構…

mysql怎么把datetime類型轉換_mysql怎樣實現time轉datetime

mysql實現time轉datetime的方法&#xff1a;使用在sql語句中【FROM_UNIXTIME(時間值)】&#xff0c;代碼為【insert into test(time) values(FROM_UNIXTIME(%d))",time(NULL)】。mysql實現time轉datetime的方法&#xff1a;FROM_UNIXTIME(time(NULL))將liunx系統的time_t類…

SpringBoot入門二

參考Spring Boot Starters - 御坂研究所 創建自己的starter starter是依賴的一種synthesize&#xff08;合成&#xff09;。 starter會把需要用到的依賴全部包含進來&#xff0c;避免開發者自己手動引入依賴。 starter的邏輯 pom.xml<parent><groupId>org.spri…