摘要:二線程池狀態(tài)當(dāng)創(chuàng)建線程池后,初始時(shí),線程池處于狀態(tài)。當(dāng)線程池處于或狀態(tài),并且所有工作線程已經(jīng)銷毀,任務(wù)緩存隊(duì)列已經(jīng)清空或執(zhí)行結(jié)束后,線程池被設(shè)置為狀態(tài)。
一、什么時(shí)候使用線程池
(1)、減少了創(chuàng)建和銷毀線程的次數(shù),每個(gè)工作線程都可以被重復(fù)利用,可執(zhí)行多個(gè)任務(wù)。
(2)、可以根據(jù)系統(tǒng)的承受能力,調(diào)整線程池中工作線線程的數(shù)目,防止因?yàn)橄倪^多的內(nèi)存,而把服務(wù)器累趴下(每個(gè)線程需要大約1MB內(nèi)存,線程開的越多,消耗的內(nèi)存也就越大,最后死機(jī)),具體可以使用Runtime.getRuntime().availableProcessors()查看虛擬機(jī)返回可用處理器的數(shù)量()。
二、線程池狀態(tài)
(1)、RUNNING : 當(dāng)創(chuàng)建線程池后,初始時(shí),線程池處于RUNNING狀態(tài)。
(2)、SHUTDOWN : 如果調(diào)用了shutdown()方法,則線程池處于SHUTDOWN狀態(tài),此時(shí)線程池不能夠接受新的任務(wù),它會(huì)等待所有任務(wù)執(zhí)行完畢。
(3)、STOP : 如果調(diào)用了shutdownNow()方法,則線程池處于STOP狀態(tài),此時(shí)線程池不能接受新的任務(wù),并且會(huì)去嘗試終止正在執(zhí)行的任務(wù)。
(4)、TIDYING : 所有任務(wù)已終止,workerCount為零,線程轉(zhuǎn)換到狀態(tài)TIDYING,運(yùn)行terminate()方法。
(5)、TERMINATED : 當(dāng)線程池處于SHUTDOWN或STOP狀態(tài),并且所有工作線程已經(jīng)銷毀,任務(wù)緩存隊(duì)列已經(jīng)清空或執(zhí)行結(jié)束后,線程池被設(shè)置為TERMINATED狀態(tài)。
三、初始化參數(shù)
(1)、corePoolSize : 線程核心線程數(shù),當(dāng)有任務(wù)進(jìn)來時(shí),當(dāng)前運(yùn)行的線程數(shù)量小于核心線程就會(huì)在創(chuàng)建線程,當(dāng)前線程等于核心線程數(shù)時(shí),任務(wù)就會(huì)被放入隊(duì)列里面,請(qǐng)參照 (5)。
(2)、maximumPoolSize : 線程池中允許的最大線程數(shù),當(dāng)線程池的線程 >= 核心線程數(shù)時(shí),并且隊(duì)列已經(jīng)放滿了任務(wù),這時(shí)線程池就會(huì)在創(chuàng)建線程去執(zhí)行任務(wù)。
(3)、keepAliveTime : 當(dāng)前線程數(shù)大于核心線程數(shù)時(shí),線程池就會(huì)找機(jī)會(huì)干掉多余的線程,當(dāng)沒有任務(wù)可以執(zhí)行時(shí),線程池會(huì)給全部線程定一個(gè)等待時(shí)間,如果過了這個(gè)時(shí)間,沒有獲得任務(wù)進(jìn)來就直接干掉線程 (當(dāng)前線程數(shù)等于或多于核心線程數(shù)時(shí),線程池首選將任務(wù)加入隊(duì)列,而不添加新的線程)。
(4)、unit : keepAliveTime的時(shí)間單位。
(5)、workQueue : 在執(zhí)行任務(wù)之前用于保留任務(wù)的隊(duì)列,(當(dāng)前線程數(shù)大于等于核心線程數(shù)時(shí),再有任務(wù)進(jìn)來就會(huì)被放到隊(duì)列里面)。
常用隊(duì)列 :
(1)、LinkedBlockingQueue,LinkedBlockingQueue是一個(gè)無界隊(duì)列,存儲(chǔ)方式使用的是鏈表
(1)、ArrayBlockingQueue,ArrayBlockingQueue是一個(gè)有界隊(duì)列,存儲(chǔ)方式使用的是數(shù)組
(1)、SynchronousQueue,SynchronousQueue是一個(gè)同步隊(duì)列沒有任何內(nèi)部容量,直接將任務(wù)交給線程,(SynchronousQueue通常要求最大線程數(shù)是無界的以避免拒絕新提交的任務(wù))。
四、使用
官方文檔強(qiáng)烈建議程序員使用較為方便的 Executors 工廠方法 Executors.newCachedThreadPool()(無界線程池,可以進(jìn)行自動(dòng)線程回收)、Executors.newFixedThreadPool(int)(固定大小線程池)和 Executors.newSingleThreadExecutor()(單個(gè)后臺(tái)線程)
五、運(yùn)行流程
(1)、當(dāng)提交一個(gè)任務(wù)!
public void execute(Runnable command) {
if (command == null) throw new NullPointerException(); int c = ctl.get(); /* 先判斷是否工作線程是否小于核心線程,如果小于就添加到調(diào)用添加工作方法。 添加成功就返回。 如果當(dāng)前線程大于等于核心線程就將任務(wù)放進(jìn)隊(duì)列里面。 */ if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) ... } if (isRunning(c) && workQueue.offer(command)) { ... } }
(2)、執(zhí)行任務(wù)
private boolean addWorker(Runnable firstTask, boolean core) {
... boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; /* 創(chuàng)建一個(gè)工作線程,將任務(wù)放進(jìn)去 */ w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int c = ctl.get(); int rs = runStateOf(c); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); /* 將所有工作放到Set集合,進(jìn)行管理 */ workers.add(w); int s = workers.size(); if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) { /* 執(zhí)行任務(wù)線程 */ t.start(); workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }
只想寫一點(diǎn)文章希望大家,多多指點(diǎn)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/69533.html
摘要:中的線程池是運(yùn)用場(chǎng)景最多的并發(fā)框架。才是真正的線程池。存放任務(wù)的隊(duì)列存放需要被線程池執(zhí)行的線程隊(duì)列。所以線程池的所有任務(wù)完成后,它最終會(huì)收縮到的大小。飽和策略一般情況下,線程池采用的是,表示無法處理新任務(wù)時(shí)拋出異常。 Java線程池 1. 簡(jiǎn)介 系統(tǒng)啟動(dòng)一個(gè)新線程的成本是比較高的,因?yàn)樗婕芭c操作系統(tǒng)的交互,這個(gè)時(shí)候使用線程池可以提升性能,尤其是需要?jiǎng)?chuàng)建大量聲明周期很短暫的線程時(shí)。Ja...
摘要:當(dāng)活動(dòng)線程核心線程非核心線程達(dá)到這個(gè)數(shù)值后,后續(xù)任務(wù)將會(huì)根據(jù)來進(jìn)行拒絕策略處理。線程池工作原則當(dāng)線程池中線程數(shù)量小于則創(chuàng)建線程,并處理請(qǐng)求。當(dāng)線程池中的數(shù)量等于最大線程數(shù)時(shí)默默丟棄不能執(zhí)行的新加任務(wù),不報(bào)任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點(diǎn)記錄以及采用的解決方案 深入分析 java 線程池的實(shí)現(xiàn)原理 在這篇文章中,作者有條不紊的將 ja...
摘要:四種線程池的使用介紹的弊端及四種線程池的使用,線程池的作用線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。相比,提供的四種線程池的好處在于重用存在的線程,減少對(duì)象創(chuàng)建消亡的開銷,性能佳。延遲執(zhí)行描述創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行。 java 四種線程池的使用 介紹new Thread的弊端及Java四種線程池的使用 1,線程池的作用 線程池作用就是限制系統(tǒng)中執(zhí)行線程的數(shù)量。 ...
系統(tǒng)啟動(dòng)一個(gè)線程的成本是比較高,使用線程池可以很好地提高性能,尤其是當(dāng)程序中需要?jiǎng)?chuàng)建大量生存期很短暫的線程時(shí) 線程池在系統(tǒng)啟動(dòng)時(shí)即創(chuàng)建大量空閑線程,將一個(gè)Runnable、Callable對(duì)象—–>傳給線程池—–>線程池啟動(dòng)里面的一個(gè)線程來執(zhí)行它們的run()或者call()方法———->當(dāng)線程執(zhí)行體執(zhí)行完成后,線程并不會(huì)死亡,而是再次返回線程池成為空閑狀態(tài),等待下一個(gè)Runnable、Calla...
摘要:高并發(fā)系列第篇文章。簡(jiǎn)單的說,在使用了線程池之后,創(chuàng)建線程變成了從線程池中獲取一個(gè)空閑的線程,然后使用,關(guān)閉線程變成了將線程歸還到線程池。如果調(diào)用了線程池的方法,線程池會(huì)提前把核心線程都創(chuàng)造好,并啟動(dòng)線程池允許創(chuàng)建的最大線程數(shù)。 java高并發(fā)系列第18篇文章。 本文主要內(nèi)容 什么是線程池 線程池實(shí)現(xiàn)原理 線程池中常見的各種隊(duì)列 自定義線程創(chuàng)建的工廠 常見的飽和策略 自定義飽和策略 ...
摘要:中的線程池運(yùn)用場(chǎng)景非常廣泛,幾乎所有的一步或者并發(fā)執(zhí)行程序都可以使用。代碼中如果執(zhí)行了方法,線程池會(huì)提前創(chuàng)建并啟動(dòng)所有核心線程。線程池最大數(shù)量線程池允許創(chuàng)建的線程最大數(shù)量。被稱為是可重用固定線程數(shù)的線程池。 Java中的線程池運(yùn)用場(chǎng)景非常廣泛,幾乎所有的一步或者并發(fā)執(zhí)行程序都可以使用。那么線程池有什么好處呢,以及他的實(shí)現(xiàn)原理是怎么樣的呢? 使用線程池的好處 在開發(fā)過程中,合理的使用線程...
閱讀 788·2021-11-24 10:19
閱讀 1187·2021-09-13 10:23
閱讀 3509·2021-09-06 15:15
閱讀 1836·2019-08-30 14:09
閱讀 1769·2019-08-30 11:15
閱讀 1905·2019-08-29 18:44
閱讀 999·2019-08-29 16:34
閱讀 2523·2019-08-29 12:46