java.util.concurrent包描述(java1.5版本引入)
在併發編程中很常用的實用工具類。此包包括了幾個小的、已標準化的可擴展框架,以及一些提供
有用功能的類。其中包括:1、執行程序(線程池);2、併發隊列;3、同步器;4、併發Collocation
線程池的作用就是限制系統中執行線程的數量;好處:
ThreadPoolExecutor線程池中的corePoolSize核心線程數,maximumPoolSize可拓展的最大線程數,
keepAliveTime(超過corePoolSize線程數時新線程)存活時間,workQueue等待隊列——存儲等待執行的任務
如果想降低系統資源消耗,包括CPU使用率,操作系統資源消耗,上下文切換開銷等,可以設置一個
較大的隊列容量,較小的maximunPoolSize。(無界隊列LikedBlockQueue)
拒絕策略有四種
AbortPolicy:直接拋出異常
CallerRunsPolicy:使用調用者所在線程執行任務
DiscardOldestPolicy:丟棄隊列中最靠前的任務,並執行當前任務
DiscardPolicy:直接丟棄當前任務
Executor線程池創建的四種線程
newFixedThreadPool:定長線程池,無界隊列,核心線程數和最大線程數一樣
newSingleThreadExecutor:單一線程池,無界隊列,核心線程數和最大線程數一樣爲1
newCacheThreadPool:緩存線程池,有界隊列,沒有核心線程數,靈活回收空閒線程
newScheduledThreadPool:定時或週期性線程池
ForkJoinPool是JDK7引入的線程池,核心思想是將超過閾值大的任務拆分成多個小任務(fork),然後再將多個
小任務處理彙總到一個結果上(join),基本線程的功能有支持設置最大併發線程數,任務排隊,線程池停止,線程池
使用監控,主要引入了“工作竊取”機制,在多CPU計算機上處理性能更佳(相對於ThreadPoolExecutor單隊列而言,它支持多隊列)
ForkJoinPool合併和分叉線程池
分叉:把自己分割成多個子任務(任務大,閾值)
合併:把自己分割成多個子任務後只需等待所有子任務執行完畢合併到同一個結果,反之不合並結果
提交任務的兩種類型:RecursiveTask(任務,有返回值)或RecursiveAction(行動,無返回值)
常用的併發隊列有阻塞隊列和非阻塞隊列,前者是使用鎖(悲觀鎖)實現,後者則使用CAS比較交換
非阻塞算法實現
ReentrantLock類也能達到同樣的效果,並且在擴展功能上更加強大,比如嗅探鎖定,
對象監視器,多路分支通知等功能
Lock和synchronized的區別
1、Lock是一個接口,而synchronized是java中的關鍵字,並且是JVM隨機獲得的內置鎖。
2、synchronized發生異常時會自動釋放線程佔有的鎖,不會導致死鎖現象發生(自動),Lock會發生死鎖現象(手動)。
3、Lock可以通過響應中斷方法讓等待鎖中斷,而synchronized不行,會讓等待的線程一直等待下去。
4、synchronized是單一控制線程,效率低下,而Lock是支持多對象監控器控制線程,效率高效
synchronized和volatile進行關鍵字的作用
volatile僅能使用在變量級別,支持共享變量——具有可見性,不具有原子性,禁止進行指令重排序,直接從主存中讀取
標記時的變量不會被編譯器優化
synchronized可以使用在變量、方法、類級別,但鎖定的是當前變量,只有當前線程可以訪問變量,保證可見性
和原子性,標記時的變量可以被編譯器優化
線程池就是事先將多個線程對象放到一個容器中,當使用的時候就不要new線程而是直接去池中拿線程即可,
節省了開闢子線程的時間,提高的代碼執行效率。
在JDK的java.util.concurrent.Executors中提供了生成多種線程池的靜態方法
ExecutorService newFixedThreadPool = ExecutorService.newFixedThreadPool(4);
特點:創建固定大小的線程池,每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小
ExecutorService newCachedThreadPool = ExecutorService.newCachedThreadPool();
特點:創建一個可緩存的線程池,此線程池不會對線程池大小做限制,線程池大小完全依賴於JVM能夠
創建的最大線程數
ExecutorService newScheduledThreadPool = ExecutorService.newScheduledThreadPool(4);
特點:創建一個大小無限的線程池,此線程池支持定時以及週期性執行任務的需求
ExecutorService newSingleThreadExecutor = ExecutorService.newSingleThreadExecutor();
特點:創建一個單線程的線程池,此線程池保證所有任務的執行順序按照任務的提交順序執行
線程池的好處(性能優點):
1、降低資源消耗。通過重複利用已經創建的線程降低線程創建和銷燬
2、提高響應速度。當任務到達時,任務可以不需要等到線程創建就能立即執行
3、提高線程的可管理性。線程是稀缺資源,如果無限制的創建,不僅會消耗系統資源,還會降低系統的穩定性,
使用線程池可以進行統一的分配,調優和監控
注:參照來源於《黑馬程序員面試寶典(java)》