並發編程:線程池詳解、Forkjoin詳解


線程池的好處

  • 降低頻繁創建、銷毀線程的開銷
  • 便於統一管理線程(數量等)
  • 提高響應時間

Java中的線程池

  • Executors:創建線程池的工廠類。
  • Executors.newFixedThreadPool(nThreads):創建固定大小的線程池。
  • Executors.newCachedThreadPool():無限線程池。
  • Executors.newSingleThreadExecutor():創建單個線程的線程池。
  • Executors.newScheduledThreadPool():創建跑定時任務的線程池。

這4個線程池底層都是調用的new ThreadPoolExcutor(),這個構造方法有很多參數,下面一一分析

  • coolPoolSize:核心線程數
  • maxPoolSize:最大線程數
  • waitTime:線程空閑等待時間
  • timeUnit:時間單位
  • 阻塞隊列
  • 拒絕策略:有4種
    • 直接拋異常
    • 直接丟棄任務
    • 將隊列中最老的任務丟掉並將新任務入隊
    • 直接用當前線程執行該任務
  • 線程工廠
這些參數和線程池的執行流程有關,線程池的執行流程:
  • 當任務提交到線程池時,假如當前線程數小於核心線程數,直接創建線程執行,並且不會銷毀,直到達到核心線程數。
  • 當核心線程都在執行還有任務提交時,任務放在阻塞隊列中。
  • 阻塞隊列也滿了以后,繼續創建線程執行任務,直到達到最大線程數。
  • 最大線程也滿了以后,執行對應的拒絕策略。
  • 當線程空閑下來以后,線程在達到線程空閑等待時間后銷毀,直至數量降低至核心線程數。

addWorker():1、增加工作線程數(cas增加一個標記位)2、創建工作線程。
Worker是一個Runnable對象,還繼承了AQS,重寫了獲取state和釋放state的方法,沒有實現重入特性。1、lock表示正在執行任務,不應該被中斷,也不應該被其他的線程重入;2、shutdown的時候會去加鎖,只有無鎖的時候才可以終止,不可重入導致shutdown不能解鎖,必須等工作結束再終止。
執行任務時會加鎖,為了在shutdown時不終止正在進行的任務。
最大線程結束的原因是while(getTask()!=null)有超時時間,返回null則跳出循環結束。

Future/Callable

實現原理:FutureTask:run()方法result字段保存返回值,保存好了以后會喚醒阻塞的線程,get()方法拿不到結果時會阻塞,內部使用awaitNode在鏈表中阻塞。

Fork/join

分治思想,拆分任務fork然后join歸並,底層實現了一種叫工作竊取的算法來提高效率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM