摘要:二線程池狀態當創建線程池后,初始時,線程池處于狀態。當線程池處于或狀態,并且所有工作線程已經銷毀,任務緩存隊列已經清空或執行結束后,線程池被設置為狀態。
一、什么時候使用線程池
(1)、減少了創建和銷毀線程的次數,每個工作線程都可以被重復利用,可執行多個任務。
(2)、可以根據系統的承受能力,調整線程池中工作線線程的數目,防止因為消耗過多的內存,而把服務器累趴下(每個線程需要大約1MB內存,線程開的越多,消耗的內存也就越大,最后死機),具體可以使用Runtime.getRuntime().availableProcessors()查看虛擬機返回可用處理器的數量()。
二、線程池狀態
(1)、RUNNING : 當創建線程池后,初始時,線程池處于RUNNING狀態。
(2)、SHUTDOWN : 如果調用了shutdown()方法,則線程池處于SHUTDOWN狀態,此時線程池不能夠接受新的任務,它會等待所有任務執行完畢。
(3)、STOP : 如果調用了shutdownNow()方法,則線程池處于STOP狀態,此時線程池不能接受新的任務,并且會去嘗試終止正在執行的任務。
(4)、TIDYING : 所有任務已終止,workerCount為零,線程轉換到狀態TIDYING,運行terminate()方法。
(5)、TERMINATED : 當線程池處于SHUTDOWN或STOP狀態,并且所有工作線程已經銷毀,任務緩存隊列已經清空或執行結束后,線程池被設置為TERMINATED狀態。
三、初始化參數
(1)、corePoolSize : 線程核心線程數,當有任務進來時,當前運行的線程數量小于核心線程就會在創建線程,當前線程等于核心線程數時,任務就會被放入隊列里面,請參照 (5)。
(2)、maximumPoolSize : 線程池中允許的最大線程數,當線程池的線程 >= 核心線程數時,并且隊列已經放滿了任務,這時線程池就會在創建線程去執行任務。
(3)、keepAliveTime : 當前線程數大于核心線程數時,線程池就會找機會干掉多余的線程,當沒有任務可以執行時,線程池會給全部線程定一個等待時間,如果過了這個時間,沒有獲得任務進來就直接干掉線程 (當前線程數等于或多于核心線程數時,線程池首選將任務加入隊列,而不添加新的線程)。
(4)、unit : keepAliveTime的時間單位。
(5)、workQueue : 在執行任務之前用于保留任務的隊列,(當前線程數大于等于核心線程數時,再有任務進來就會被放到隊列里面)。
常用隊列 :
(1)、LinkedBlockingQueue,LinkedBlockingQueue是一個無界隊列,存儲方式使用的是鏈表
(1)、ArrayBlockingQueue,ArrayBlockingQueue是一個有界隊列,存儲方式使用的是數組
(1)、SynchronousQueue,SynchronousQueue是一個同步隊列沒有任何內部容量,直接將任務交給線程,(SynchronousQueue通常要求最大線程數是無界的以避免拒絕新提交的任務)。
四、使用
官方文檔強烈建議程序員使用較為方便的 Executors 工廠方法 Executors.newCachedThreadPool()(無界線程池,可以進行自動線程回收)、Executors.newFixedThreadPool(int)(固定大小線程池)和 Executors.newSingleThreadExecutor()(單個后臺線程)
五、運行流程
(1)、當提交一個任務!
public void execute(Runnable command) {
if (command == null) throw new NullPointerException(); int c = ctl.get(); /* 先判斷是否工作線程是否小于核心線程,如果小于就添加到調用添加工作方法。 添加成功就返回。 如果當前線程大于等于核心線程就將任務放進隊列里面。 */ if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) ... } if (isRunning(c) && workQueue.offer(command)) { ... } }
(2)、執行任務
private boolean addWorker(Runnable firstTask, boolean core) {
... boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; /* 創建一個工作線程,將任務放進去 */ 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集合,進行管理 */ workers.add(w); int s = workers.size(); if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) { /* 執行任務線程 */ t.start(); workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }
只想寫一點文章希望大家,多多指點。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69533.html
摘要:當活動線程核心線程非核心線程達到這個數值后,后續任務將會根據來進行拒絕策略處理。線程池工作原則當線程池中線程數量小于則創建線程,并處理請求。當線程池中的數量等于最大線程數時默默丟棄不能執行的新加任務,不報任何異常。 spring-cache使用記錄 spring-cache的使用記錄,坑點記錄以及采用的解決方案 深入分析 java 線程池的實現原理 在這篇文章中,作者有條不紊的將 ja...
摘要:四種線程池的使用介紹的弊端及四種線程池的使用,線程池的作用線程池作用就是限制系統中執行線程的數量。相比,提供的四種線程池的好處在于重用存在的線程,減少對象創建消亡的開銷,性能佳。延遲執行描述創建一個定長線程池,支持定時及周期性任務執行。 java 四種線程池的使用 介紹new Thread的弊端及Java四種線程池的使用 1,線程池的作用 線程池作用就是限制系統中執行線程的數量。 ...
摘要:高并發系列第篇文章。簡單的說,在使用了線程池之后,創建線程變成了從線程池中獲取一個空閑的線程,然后使用,關閉線程變成了將線程歸還到線程池。如果調用了線程池的方法,線程池會提前把核心線程都創造好,并啟動線程池允許創建的最大線程數。 java高并發系列第18篇文章。 本文主要內容 什么是線程池 線程池實現原理 線程池中常見的各種隊列 自定義線程創建的工廠 常見的飽和策略 自定義飽和策略 ...
閱讀 729·2021-11-24 10:19
閱讀 1106·2021-09-13 10:23
閱讀 3428·2021-09-06 15:15
閱讀 1777·2019-08-30 14:09
閱讀 1683·2019-08-30 11:15
閱讀 1837·2019-08-29 18:44
閱讀 934·2019-08-29 16:34
閱讀 2456·2019-08-29 12:46