這篇文章主要講解了“Java線程池是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java線程池是什么”吧!
身為程序員我們對線程是再熟悉不過了,多線程并發算是Java進階的知識,用好多線程不容易有太多的坑。創建線程也算是一個"重"操作。創建線程的語句是new Thread()咋一看好像就是new了一個對象。
沒錯是new了個對象,但是不僅僅是普通對象那樣在堆中分配了一塊內存,它還需要調用操作系統內核API,然后操作系統再為線程分配一些資源。所以較普通對象,線程就比較“重了”。所以我們要避免頻繁的創建和銷毀線程,還得控制一下線程的數量。線程池就是用來完成這一項使命的。
所以多線程就離不開線程池,所以要掌握多線程編程,線程池的了解必不可少。
線程池的設計就是采用生產者-消費者模式,線程池里面的線程是消費者,我們塞給線程池的任務是生產者??梢岳斫獬删€程池就是火車站售票廳,線程池里面的線程就是火車站售票廳窗口員工,我們去買票或者退票改簽就是給窗口員工任務也就是生產,然后窗口員工幫我們辦理業務,也就是消費。
一般我們是用ThreadPoolExecutor來創建線程池,我找了里面參數最多的構造器。
1、corePoolSize
按字面翻譯過來就是核心池大小,其實就是線程池保有的最小的線程數,這里需要注意一下,初始化線程池的時候,除非調用prestartAllCoreThreads或者prestartCoreThread這兩個方法,這兩個方法分別是在無任務到來之前預創建所有核心線程或者創建一個線程。否則線程池初始化后沒任務進來前是沒有線程的。只有當任務來了才會創建線程。
所以這里保有的核心數指的是,當線程池創建了這么多的線程之后,會保留的不會被回收的線程數,超過corePoolSize的線程在一定時間之后就會被回收。
但是java1.6新增了一個allowCoreThreadTimeOut(boolean value)方法,當設為true時候,所有的線程都會超時回收,包括核心線程。
2、maximumPoolSize
最大線程數,也就是池里面能有的最大的線程數量。也就是火車站售票廳窗口所有的窗口都有員工在服務。特別是在節假日的時候,基本上窗口都會開放。
3、keepAliveTime、TimeUnit
keepAliveTime就是存活時間,TimeUnit是時間單位,來表明keepAliveTime的數字是秒啊還是毫秒啊等等。
這兩個參數就是當我們線程池存在的線程數量超過corePoolSize時,如果有個線程已經空閑了keepAliveTime這么長的時間,那么這個空閑線程就要被回收了,就類似于出行高峰期過去了,售票廳窗口可以關閉幾個了??偛荒芏紱]人了還開這么多窗口把,浪費呀。
4、workQueue
工作隊列,是阻塞隊列。隊列存儲的也就是線程需要執行的Runnable,也就是任務。對應著就是去售票廳排隊的我們。
5、threadFactory
按名字翻譯過來就是線程工廠了,也就是我們可以搞個工廠,然后自定義如何創建線程,比如給線程set下名字啊等。然后線程池就會按照工廠定義的方式創建線程。就是如果不設定線程的名字的話,線程名可能就是什么thread-1這樣的,對于我們排查問題不太方便,所以給個名字來標識一下比較好。
6、handler
這個是拒絕策略,也就是當線程池中所有的線程都在執行任務,并且工作隊列(是有界隊列)也排滿了,那再有任務提交就會執行拒絕策略。ThreadPoolExecutor提供了四種拒絕策略
1、ThreadPoolExecutor.AbortPolicy()
是默認的拒絕策略,會拋出 RejectedExcecutionException。
2、ThreadPoolExecutor.CallerRunsPolicy()
讓提交任務的線程自己去執行這個任務。。好像這樣做挺有道理的..我沒空你自己搞去
3、ThreadPoolExecutor.DiscardOldestPolicy()
丟棄最老的任務,也就是工作隊列里最前面的任務,丟棄了之后把新任務加入到工作隊列中...真的不公平啊
4、ThreadPoolExecutor.DiscardPolicy()
直接丟棄任務,并且不拋出任何異常...假裝沒看到系列
除了這四種還可以自定義拒絕策略,建議自定義拒絕策略。因為更加的友好,可以設置成服務降級啊等操作。
注意
Java并發包還提供了Executors,可以快速創建線程池,但是不推薦使用Executors。因為Executors創建線程池都是默認使用無界隊列LinkedBlockingQueue,在高負載的情況下容易OOM。所以建議使用有界隊列。
總結
所以線程池就是生產者-消費者模型的實現,線程池約束了線程的數量,也避免頻繁的創建和銷毀線程。工作隊列得存在使得任務有序的進行,完美!
感謝各位的閱讀,以上就是“Java線程池是什么”的內容了,經過本文的學習后,相信大家對Java線程池是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。