1. 程式人生 > >線程池管理(1)-為什麽需要線程池

線程池管理(1)-為什麽需要線程池

一起 問題 創建 jpg 們的 ava 消費者 service 執行時間

摘要

為什麽需要線程池呢,沒想明白這個問題,看再多線程池的源碼都沒有用,先要知道線程池技術解決了什麽問題,才能看的懂源碼,因為所有的代碼都是為了解決實際的工程問題。

問題

拋幾個問題,看看你是否知道,不知道的話,可能你對線程池的理解還不夠深入,還是一知半解。那麽本文會對你有用,請繼續看下去

  • 線程池的線程數可以為1嗎?
  • 線程數為1的線程池有存在的必要嗎
  • 2個有5個核心線程的線程池和1個有10個核心線程的線程池有什麽區別
  • 一個應用中如何管理線程池
  • 線程池池化技術和消息隊列有什麽區別

線程池原理

在大學裏我們學習c語言時,一個main函數寫到底,就可以交作業了。剛開始工作時,mvc一路controller -> service -> dao就OK了。但是工作中寫代碼是要解決實際問題的。你啪啪啪寫完了代碼,用戶發現你這個接口響應太慢了,怎麽辦?

技術分享圖片
用戶提交任務到程序執行完成,大致的過程如上圖,提交一個task,然後有個線程去執行。
所以要提高?程序執行的效率可以從兩個方面來考慮

  1. 異步,先響應,返回中間結果,然後異步處理,將結果返回
  2. 並發,多個線程來執行。

本篇說的線程池主要就是從1的維度來提高程序執行的效率

生產者消費者模式

有一定工作經驗的朋友對消息隊列的削峰填谷,系統解耦肯定不陌生。那麽線程池,算不算削峰填谷呢?
異步化後,相當於把所有的task放在了隊列中。也就是生產者 -> 容器 -> 消費者。如下圖
技術分享圖片
從圖可以看出,線程池技術使系統復雜了,也提供了更多的靈活性。通過隊列的形式,我們將任務的執行拆分成了生產者,消費者模式。每一步只用關心自己的事情。如果我們的任務很復雜,我們可以將任務拆分成不同的步驟,每一步驟可以使用不同的線程池來解決,以此來提高效率。

可管理性

看上去通過線程池完美解決了我們的問題,那麽需要付出什麽代價呢?cpu的資源是有限的,線程的創建也需要代價,我們一個java應用進程的資源是畢竟是有限的。我們不可能在應用中無限的創建線程池。所以我們需要管理線程池。

通常,對於簡單的應用,我們使用一個單例線程池即可,讓應用中的所有task都使用同一個線程池,防止一些初級程序員在應用中隨意創建線程池,導致線程資源吃緊,線程占用過多的資源。

當應用中task比較復雜的時候,我們就需要使用分治的思想,對線程池進行隔離。
比如有些是cpu密集型的,有些是IO密集型的;任務的重要程度也有輕重之分;任務的執行時間也有不同。我們需要對為這些任務建立不同的線程池,以此來提高效率。

總結

線程池是一種異步化技術,通過預先創建線程/異步處理來提高響應速度。同時通過統一調配線程資源,可以降低線程的重復創建問題,提高線程的利用率,中心化管理有利於對資源的有效控制,防止濫用。

關註【方丈的寺院】,與方丈一起開始技術修行之路

技術分享圖片

線程池管理(1)-為什麽需要線程池