為什麼不應該自動建立執行緒池?

2021-10-09 08:53:57 字數 1709 閱讀 7319

首先我們來看執行緒池 fixedthreadpool, 它是執行緒數量固定的執行緒池,如原始碼所示,newfixedthreadpool 內部實際還是呼叫了 threadpoolexecutor 建構函式

public static executorservice newfixedthreadpool(int nthreads)
通過往建構函式中傳參,建立了乙個核心執行緒數和最大執行緒數相等的執行緒池,它們的數量也就是我們傳入的引數,這裡的重點是使用的佇列是容量沒有上限的 linkedblockingqueue,如果我們對任務的處理速度比較慢,那麼隨著請求的增多,佇列中堆積的任務也會越來越多,最終大量堆積的任務會占用大量記憶體,並發生oom,也就是outofmemoryerror,這幾乎會影響到整個程式,會造成很嚴重的後果

public static executorservice newsinglethreadexecutor()
newsinglethreadexecutor 和 newfixedthreadpool 的原理是一樣的,只不過把核心執行緒數和最大執行緒數都直接設定成了 1,但是任務佇列仍是無界的 linkedblockingqueue,所以也會導致同樣的問題,也就是當任務堆積時,可能會占用大量的記憶體並導致oom

public static executorservice newcachedthreadpool()
這裡的 cachedthreadpool 和前面兩種執行緒池不一樣的地方在於任務佇列使用的是 synchronousqueue,synchronousqueue本身並不儲存任務,而是對任務直接進行**,這本身是沒有問題的,但你會發現建構函式的第二個引數被設定成了integer.max_value,這個引數的含義是最大執行緒數,所以由於cachedthreadpool 並不限制執行緒的數量,當任務數量特別多的時候,就可能會導致建立非常多的執行緒,最終超過了作業系統的上限而無法建立新執行緒,或者導致記憶體不足

public static scheduledexecutorservice newscheduledthreadpool(int corepoolsize)
而這裡的scheduledthreadpoolexecutor是 threadpoolexecutor 的子類,呼叫的它的構造方法如下所示

public scheduledthreadpoolexecutor(int corepoolsize)
通過原始碼可以看出,它採用的任務佇列是delayedworkqueue,這是乙個延遲佇列,同時也是乙個無界佇列,所以和linkedblockingqueue一樣,如果佇列中存放過多的任務,就可能導致oom

可以看到,這幾種自動建立的執行緒池都存在風險,相比較而言,我們自己手動建立會更好,因為我們可以更加明確執行緒池的執行規則,不僅可以選擇適合自己的執行緒數量,更可以在必要的時候拒絕新任務的提交,避免資源耗盡的風險

為什麼不應該買小房換大房?

一 基本邏輯 邏輯1 房價目前處於高位,未來的10年房價很難在保持高速增長,每年 預計最多漲幅平均在3 左右 邏輯2 小房子 90平公尺以下 無法滿足家庭居住的需求,隨著身邊朋友都換了好房子及大房子,痛苦指數將倍增,將來一定還需要換大房子 邏輯3 租房的成本為年化3 左右,即總花費100萬的房子 房...

為什麼在析構函式中不應該丟擲異常

1.丟擲異常 1.1 丟擲異常 也稱為拋棄異常 即檢測是否產生異常,在c 中,其採用throw語句來實現,如果檢測到產生異常,則丟擲異常。該語句的格式為 throw 表示式 如果在try語句塊的程式段中 包括在其中呼叫的函式 發現了異常,且拋棄了該異常,則這個異常就可以被try語句塊後的某個catc...

為什麼不應該重複競爭對手的SEO策略?

wendy s 餐廳的創始人托馬斯曾經說過,他要把餐廳開到每一家麥當勞分店的對面去。這是乙個明智的策略。很顯然,電腦城,批發城也運用同種原理,因為在那種地方,大家的客戶都是一樣的。麥當勞在籌備每家新分店的時候都會做了大量的調查研究,所以托馬斯認為,麥當勞準備進軍當地市場,肯定是覺得有利可圖。對於跟麥...