java如何创建一个两个数的队列_java线程池 如何构建一个线程立即到拉到MAX数量跑业务,线程到MAX了,额外的队列可以存储任务的线程池...
背景:JDK的線程池的運作原理 :
JDK的線程池的構造函數有7個參數,分別是corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。先復習一下 https://blog.csdn.net/ye17186/article/details/89467919
上述內容是網上對于線程池的參數的描述,需要關注的一個點:
1)任務進入線程池隊列,先啟動WORKER線程到 CORE的數量,然后再填寫線程池的緩沖隊列,隊列滿了以后(如果可以滿),再增加WORKER線程到MAX配置數量。
下面是源碼:(源碼就是這樣,也驗證過,是這個邏輯,簡單說,先CORE 再隊列,隊列滿了以后再拉線程到MAX數量)
2)這樣會有缺陷,為什么一定要 滿足 隊列滿了,再拉線程,我想優先拉線程怎么辦 ? 不好意思,JDK只有一個辦法:設置隊列大小為1,那么就基本上馬上就會拉新線程了(但是作為數據緩沖區的隊列,削峰填谷的優勢就無法使用了)
那么如果期望 優先 先拉線程數量到MAX,再把任務放到隊列緩存區怎么辦 ?
業務場景需要滿足: 1)任務量大了,線程立即到拉到MAX 數量跑業務。 2)線程到MAX了,額外的隊列可以存儲任務,做削峰填谷使用。
(core size是閑時最低線程數量,如果線程數量太多,會導致線程內存開銷以及 太多線程無效輪詢消耗)
方案一: 看到源碼,自己去實現一個線程池的實現,重寫EXECUTE方法,調整邏輯,先拉WORKER到MAX然后放入隊列可以達成
項目中,準備上方案一的時候,發現代碼量不小,這個問題應該很多人都遇到了,有沒有現成的可以使用?
重寫JDK源碼會帶來工作量,維護,以及升級JDK的風險,明顯是一種不好的辦法。
方案二:再找就發現了這樣一篇文檔:
果然,遇到這個問題的不止一個, 事實上 tomcat 和dubbo 都這樣干了!
非常有意思的是,是在隊列的OFFER函數中做文章(有點欺騙JDK的線程池 EXECUTE的意思)很難想到這種方案。
我們要使用:兩行代碼就滿足了我們的訴求:
引用對象:當然是用DUBBO也是一樣,已驗證、有效。
PS: 額外的思考:
1)為什么?JDK默認要使用先隊列再拉MAX WORKER的方式? 可能是JDK認為線程池任務大多數都是 CPU密集型的任務,那么啟動太多的CPU帶來的價值不大、或者拉線程的有成本,隊列滿了再拉。
2)怎么選?如果任務是CPU密集使用JDK自帶的線程池策略就夠了,如果是IO型任務,有較多阻塞場景(這就是為什么TOMCAT 和RPC的DUBBO需要的原因)就需要使用線程數優先,再進入隊列的模式(IO密集型任務,有IO阻塞,JDK自帶線程池的策略難以滿足要求)。
3)客觀的說,JDK應該把這個配置 做成配置項(到底是先進入隊列,再拉線程到MAX,還是先拉線程到MAX再進入隊列)
總結
以上是生活随笔為你收集整理的java如何创建一个两个数的队列_java线程池 如何构建一个线程立即到拉到MAX数量跑业务,线程到MAX了,额外的队列可以存储任务的线程池...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java9新特性 2017_Java 9
- 下一篇: 短url服务java_Serverles