threadpooltaskexecutor线程池使用_(四)为什么要使用线程池
阿里開發手冊有一段描述:
【強制】線程資源必須通過線程池提供,不允許在應用中自行顯式創建線程。
說明:使用線程池的好處是減少在創建和銷毀線程上所花的時間以及系統資源的開銷,解決資源不足的問題。如果不使用線程池,有可能造成系統創建大量同類線程而導致消耗完內存或者“過度切換”的問題。
上一篇文章介紹了Java線程是什么,以及用顯式創建線程的兩種方式(繼承Thread類或者實現Runnable接口):
1. 手動創建線程的缺點
繼承extend類或者實現runnable接口都是最簡單創建線程的方式,但是這種方式有以下缺點:
不受風險控制
頻繁創建,開銷大
不好管理(不知道哪里創建了線程、線程名字可能沒有)
1.1 不受風險控制
服務器CPU資源有限,如果每個人都顯示手動創建線程,不知道哪里的代碼出現了多線程,在運行的時候所有線程都在搶占資源,不好控制。
1.2 頻繁創建,開銷大
雖然說new Theard()的父類也是Object,但是new Theard()和new Object()還是有區別的。
以下參考:我會手動創建線程,為什么讓我使用線程池?
new Object()過程:
分配一塊內存 M
在內存 M 上初始化該對象
將內存 M 的地址賦值給引用變量 obj
創建一個線程的過程:
它為一個線程棧分配內存,該棧為每個線程方法調用保存一個棧幀
每一棧幀由一個局部變量數組、返回值、操作數堆棧和常量池組成
一些支持本機方法的 jvm 也會分配一個本機堆棧
每個線程獲得一個程序計數器,告訴它當前處理器執行的指令是什么
系統創建一個與Java線程對應的本機線程
將與線程相關的描述符添加到JVM內部數據結構中
線程共享堆和方法區域
這段描述稍稍有點抽象,用數據來說明創建一個線程(即便不干什么)需要多大空間呢?答案是大約 ?1M ?左右
1.3 不好管理
線程的名字不統一,可能無限制新建線程,可能占用過多系統資源導致死機或OOM。而重用存在的線程,減少對象創建、消亡的開銷,性能佳。
2. 什么是線程池
在Java 5之后,Java通過Executor來啟動線程,比使用Thread的start方法更好,除了更易管理,效率更好(用線程池實現,節約開銷)外,還有關鍵的一點:有助于避免this逃逸問題。
簡單的說就是把線程統一管理。
線程池優勢:
(1)降低系統資源消耗,通過重用已存在的線程,降低線程創建和銷毀造成的消耗;
(2)提高系統響應速度,當有任務到達時,通過復用已存在的線程,無需等待新線程的創建便能立即執行;
(3)方便線程并發數的管控。因為線程若是無限制的創建,可能會導致內存占用過多而產生OOM,并且會造成cpu過度切換(cpu切換線程是有時間成本的(需要保持當前執行線程的現場,并恢復要執行線程的現場))。
(4)提供更強大的功能,延時定時線程池。
Java的4種默認線程池:
newSingleThreadExecutor
創建一個單線程的線程池。這個線程池只有一個線程在工作,也就是相當于單線程串行執行所有任務。如果這個唯一的線程因為異常結束,那么會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。
newFixeThreadPool
創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那么線程池會補充一個新線程。
newCachedThreadPool
創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,那么就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(或者說JVM)能夠創建的最大線程大小。
newScheduledThreadPool
創建一個大小無限的線程池。此線程池支持定時以及周期性執行任務的需求。
參考:
我會手動創建線程,為什么讓我使用線程池
--end--
長按關注噢!萬水千山總是情,點個在看行不行總結
以上是生活随笔為你收集整理的threadpooltaskexecutor线程池使用_(四)为什么要使用线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos找不到chattr命令_一个
- 下一篇: python图像识别车票_是程序员就用P