線程池,以及線程池的實現以及面試常問的問題,工廠模式,常見的鎖策略(面試常考,要了解,不行就背)

一、💛

線程池的基本介紹

內存池,進程池,連接池,常量池,這些池子概念上都是一樣的~~

如果我們需要頻繁的創建銷毀線程,此時創建銷毀的成本就不能忽視了,因此就可以使用線程池。

提前創建好一波線程,后續需要使用線程,就直接從池子里面拿一個即可,當線程不再使用,就放回池子里面。(本來是需要創建線程/銷毀線程,現在是從池子里面獲取到現成的線程,并且把線程歸還到池子里面

那么為啥從池子里面拿就比系統里面創建線程更加高效呢?

不用線程池:如果是系統這里創建線程,需要調用系統API,進一步的由操作系統內核完成,完成線程的創建過程(內核是給所有進程提供服務的,這樣你想干的事情,就需要等一等,等多長時間我們是未知的,是不可以控制的)

使用線程池:上述的內核中進行的操作都是提前做好了的,現在的取線程過程,純粹的是用戶使用代碼完成的(純用戶態)-是可控制的。

二、💙

工廠模式:去生產的功能(字面意思),用于生產對象,一般情況下我們創建對象都是new,通過構造方法,但是構造方法有時候存在巨大的缺陷(構造方法是固定就是類名,有的類需要使用多種不同構造方式->(方法重載僅要求參數的個數和類型有區別)

~比如說:表示坐標->這種無法構成重載

public class Circle {public Circle(double x,double y){         //笛卡爾坐標};public  Circle(double r,double a){        //極坐標};
}
所以上面的代碼也不對,構不成方法重載

使用工廠模式來解決上述問題,不使用構造方法來,(我剛開始也在想為什么是靜態,直到我自己去試一下,明白了也就是說不用構造方法創建對象,假如不是靜態方法,那么該怎么調用他呢,不是靜態的,可是只能用對象.方法才可以調用)用普通方法來構造對象,這樣方法就可以任意的了,普通方法內部去new對象~由于普通方法的目的是創建對象,然后調用方法來設置屬性,所以方法一般都是靜態的。(類名.方法)

三、💜?

//Executors:工廠類,后面的是工廠方法。這句話是創建一個固定線程數量的線程池
//線程池對象:ExecutorService serviceExecutorService service= Executors.newFixedThreadPool(4);
//創建一個線程數組,動態變化的線程池。ExecutorService service2= Executors.newCachedThreadPool();
//包含單個線程(比原生創建API更簡單一些指Thread)ExecutorService service3= Executors.newSingleThreadExecutor();
//類似于定時器效果,添加一些任務,執行,被執行的時候,不是只有有一個掃描線程來執行,可能是有多個共同執行ExecutorService service4= Executors.newScheduledThreadPool();}

?

四、??

面試題:談談java庫中的線程池構成方法的參數和含義

這個方法最復雜,而且別的參數這個參數都有,所以就只解釋這個方法就行。

int corePoolSize:核心線程數

int maximunPoolSize:最大線程數

ThreadPoolExcutor:里面的線程個數,并

非固定不變的,會根據當前任務的情況動態變化(自適應)

corePoolSize:至少要這些線程,哪怕你的線程都沒任務也要這些個線程(如同公司里面的正式員工)

maximumPoolSize:最多不超過這些線程,哪怕干冒煙了,也不能比這個更多了(正式員工+實習生)

long keepAliveTime, TimeUnit unit:實習生線程,空閑時間超過指定閾值(允許實習生摸魚的最大時間),就可以銷毀了

BlockingQueue<Runnable>workQueue:線程池內部有很多很多,任務可以使用阻塞隊列管理,線程池可以內置阻塞隊列,也可以手動一個。

RejectedExecutionHandler ? handler:線程池考的重點,拒絕方式/拒絕策略,線程池有一個阻塞隊列,當隊列滿了,繼續加任務如何處理。

1.ThreadPoolExecutors.AbortPolicy:直接拋出異常,線程池就不干活了,(小王喊我打球,我在學習,我直接崩潰了,我哇哇大哭)

2.ThreadPoolExecutor.callerRunsPolicy:誰說添加這個任務的線程,誰就去執行這個任務

,我會直接說:我沒空,自己投去吧)

3.ThreadPoolExecutor.DiscardPolicy:把新的任務丟棄,(不打球了,我接著學習)

4.ThreadPoolExecutor.DiscardPolicy:丟棄最早的任務,執行新的任務(放棄學習,去打球)

有的線程公司會推薦使用這個。

?

五、💚?

具體實現一個線程池

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;class MyThreadPool {private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();//通過這個方法把任務添加到線程池中public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}//n表示一個線程池里面有幾個字段,創建了一個固定數量的線程池public MyThreadPool(int n) throws InterruptedException {for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {while (true) {Runnable runnable = null;try {runnable = queue.take();      //從隊列中提取這個任務} catch (InterruptedException e) {e.printStackTrace();}runnable.run();                  //運行這個任務}});t.start();                              //開啟這個線程}}
}
public class Demo4 {public static void main(String[] args) throws InterruptedException {//獲取當前引用實例MyThreadPool myThreadPool = new MyThreadPool(4);for (int i = 0; i < 1000; i++) {               //循環很關鍵哈,這個循環是添加1000次任務,但是假如你放到run里面,就會變成一個任務,至少內容是執行1000遍,線程是執行多個任務,但是不能一個任務還分擔myThreadPool.submit(new Runnable() {           //(安排任務,安排一個任務)@Override                                  //這個任務進行的工作public void run() {System.out.println(Thread.currentThread().getName() + " love");}});}}
}

面試問題2號:創建線程池的時候,線程個數怎么數的:

網路上查資料很多:假設cpu邏輯數是N,線程的個數:N,N+1,2N···

準確的說都不準確,因為不同的項目要做的工作是不同的:

cpu密集型線程工作:全是運算大部分工作在cpu上完成,cpu給他安排核心,才能概括,假如cpu N個核心,線程數量最好也是為N,如果多了,線程也只能是排隊等待,沒有新的進展

Io密集型線程工作:涉及大量等待時間,等待的過程,不要cpu,所以這里線程多,也會給cpu造成負擔,cpu16核,整個32個線程,不犯毛病(不耗cpu,甚至cpu占用很低)———

實際上,一部分cpu密集,一部分Io密集,是我們工作中的常態,此時一個線程多少在cpu上執行,多少等待IO,說不好,更好的做法:自己去性能測試一下,找到性能和開銷比較均衡的數值


六、💔?

多線程進階開啟:

常見的鎖策略

如果工作中,真正要實現一把鎖,需要理解鎖策略

1.樂觀鎖VS悲觀鎖

樂觀鎖:預測,不太會出現鎖沖突的情況

悲觀鎖:預測,這個場景非常容易鎖沖突

2.重量級鎖VS輕量級鎖

重量級鎖:加鎖開銷比較大,花的時間多,占有系統資源,一個悲觀鎖,很可能是重量級鎖

輕量級鎖:花的時間少,占有資源少,加鎖的開銷比較小的,很可能是樂觀鎖

悲觀,樂觀是加鎖之前堆沖突概率的預測,決定工作的多少,重量,輕量,是加鎖后,考慮實際的鎖開銷

3.自旋鎖VS刮起等待鎖

自旋鎖是輕量級的一種典型實現,在用戶態通過自旋的方式(while循環),實現類似加鎖的操作(一直在瘋狂的舔,這種鎖會耗一定的cpu,但是是最快速度拿到鎖的)

掛起等待鎖:通過內核態,借助系統提供的鎖機制,當出現鎖沖突,會牽扯到內核對線程的調度,是沖突的線程出現掛起(阻塞等待)重量級鎖的一種典型體現,發現鎖被占用后,自己該干啥干啥,偶爾聽到了消息,又去找這個鎖,耗費cpu少,但無法第一時間拿到鎖(小擺爛)

4.讀寫鎖VS互斥鎖

讀寫鎖:把讀操作,寫操作分開了

假如兩個線程 一個讀加鎖,另一個還是讀加鎖,那么兩個不會有鎖競爭(目的:就是把這種情況處理,這樣多線程的效率會更高)

一個讀,一個寫,兩個都是寫都會有鎖競爭,但是兩個讀沒事,在開發中讀操作會比寫操作更加頻繁

互斥鎖:寫了就不能讀,讀了就不可以寫,

5.公平鎖VS非公平鎖

公平鎖是遵循先來后到這個規則的

非公平鎖相當于超市促銷,都來搶位置,不遵守順序

操作系統自帶鎖(pthread-mutex)是非公平鎖,要實現公平鎖,就需要一些額外的數據結構來支持(比如需要有辦法記錄每個線程的阻塞等待時間)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/34987.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/34987.shtml
英文地址,請注明出處:http://en.pswp.cn/news/34987.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中使用instanceof判斷對象類型

記錄&#xff1a;470 場景&#xff1a;Java中使用instanceof判斷對象類型。例如在解析JSON字符串轉換為指定類型時&#xff0c;先判斷類型&#xff0c;再定向轉換。在List<Object>中遍歷Object時&#xff0c;先判斷類型&#xff0c;再定向轉換。 版本&#xff1a;JDK 1…

Redis系列(一):深入了解Redis數據類型和底層數據結構

Redis有以下幾種常用的數據類型&#xff1a; redis數據是如何組織的 為了實現從鍵到值的快速訪問&#xff0c;Redis 使用了一個哈希表來保存所有鍵值對。 Redis全局哈希表&#xff08;Global Hash Table&#xff09;是指在Redis數據庫內部用于存儲所有鍵值對的主要數據結構。…

安卓13不再支持PPTP怎么辦?新的連接解決方案分享

隨著Android 13的發布&#xff0c;我們迎來了一個令人興奮的新品時刻。然而&#xff0c;對于一些用戶而言&#xff0c;這也意味著必須面對一個重要的問題&#xff1a;Android 13不再支持PPTP協議。如果你是一個習慣使用PPTP協議來連接換地址的用戶&#xff0c;那么你可能需要重…

C++ 泛型編程:函數模板

文章目錄 前言一、什么是泛型編程二、函數模板三、函數模板的使用四、多參數函數模板五&#xff0c;示例代碼&#xff1a;總結 前言 當需要編寫通用的代碼以處理不同類型的數據時&#xff0c;C 中的函數模板是一個很有用的工具。函數模板允許我們編寫一個通用的函數定義&#…

Vue day02 Computed和Watch

1.事件綁定 可以用 v-on 指令監聽DOM 事件&#xff0c;并在觸發時運行一些 JavaScript 代碼。v-on 還可以接收一個需要調用的方法名稱。 <button v-on:click"handler">good</button> methods: { handler: function (event) { if (event) { alert(event.t…

接口測試之Jmeter+Ant+Jenkins接口自動化測試平臺

平臺簡介 一個完整的接口自動化測試平臺需要支持接口的自動執行&#xff0c;自動生成測試報告&#xff0c;以及持續集成。Jmeter支持接口的測試&#xff0c;Ant支持自動構建&#xff0c;而Jenkins支持持續集成&#xff0c;所以三者組合在一起可以構成一個功能完善的接口自動化…

BOLT- 識別和優化熱門的基本塊

在BOLT中&#xff0c;識別和優化熱門的基本塊之所以關鍵&#xff0c;是因為BOLT的主要目標是優化程序以更好地利用硬件特性&#xff0c;特別是指令緩存&#xff08;ICache&#xff09;。以下是BOLT如何識別和優化熱門基本塊的流程&#xff1a; 收集性能數據: BOLT開始的時候并不…

idea - 刷新 Git 分支數據 / 命令刷新 Git 分支數據

一、idea - 刷新 Git 分支數據 idea 找到 fetch 選項&#xff0c;重新獲取分支數據 二、命令刷新 Git 分支數據 git fetch參考鏈接 1. 遠程Gitlab新建的分支在IDEA里不顯示

jxls導出問題

![請添加圖片描述](https://img-blog.csdnimg.cn/bc74c4207818491c93b75e19b3333451.png 為什么最后導出的文件還是按原樣導出啊&#xff0c;沒有填充數據 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/d4500b9a98c042f6b64a5d0650071303.png

qt多線程使用方式

有5個方式&#xff1a;可以參考這個博客&#xff1a;Qt 中開啟線程的五種方式_qt 線程_lucky-billy的博客-CSDN博客 注&#xff1a;為了實現更加靈活的線程管理&#xff08;因為這5種都有一些不方便之處&#xff1a;QThread需要子類化且不能傳參&#xff0c;moveToThread不能傳…

【leetcode】459. 重復的子字符串(easy)

給定一個非空的字符串 s &#xff0c;檢查是否可以通過由它的一個子串重復多次構成。 示例 1: 輸入: s “abab” 輸出: true 解釋: 可由子串 “ab” 重復兩次構成。 示例 2: 輸入: s “aba” 輸出: false 示例 3: 輸入: s “abcabcabcabc” 輸出: true 解釋: 可由子串 “ab…

ChatGPT等人工智能編寫文章的內容今后將成為常態

BuzzFeed股價上漲200%可能標志著“轉向人工智能”媒體趨勢的開始。 周四&#xff0c;一份內部備忘錄被華爾街日報透露BuzzFeed正計劃使用ChatGPT聊天機器人-風格文本合成技術來自OpenAI&#xff0c;用于創建個性化盤問和將來可能的其他內容。消息傳出后&#xff0c;BuzzFeed的…

ubuntu 20.04 RK3568網絡的優先級設置

1、背景 硬件使用RK3568 CPU&#xff0c;操作系統采用ubuntu 20.04 Lxqt桌面的版本。硬件上具有一個有線以太網卡&#xff0c;一個wifi網卡&#xff0c;一個5G網卡。由于操作系統默認的網絡優先級為有線網卡的最高&#xff0c;5G網卡次之。在一個業務應用中需要5G網卡的連接外…

文本三劍客之grep命令和awk命令 1.0 版本

grep awk 1.grep命令1.1 基本格式1.2 常用選項 2.awk命令2.1 awk工作原理2.2 awk命令格式2.3 awk常用內置變量 1.grep命令 1.1 基本格式 grep [選項]… 查找條件 目標文件1.2 常用選項 選項功能 -m [ x ]匹配x次 后停止,x為具體數字-v取反 -i忽略字符大小寫 -n顯示匹配的 …

Dynamic CRM開發 - 實體介紹

實體簡介 在CRM中,實體(Entity)是數據的基本載體,也是構建業務邏輯網絡的基礎節點。 實體可以理解為數據庫中的一張表(實體中的字段對應數據庫表的字段),比如創建一個實體存儲客戶信息,創建一個實體存儲產品信息,產品實體里可以創建一個查找類型的字段(類似表的外鍵)…

【Express.js】集成RabbitMQ

集成RabbitMQ 本節我們介紹在 express.js 中集成 rabbitmq. RabbitMQ 是一個消息隊列中間件&#xff0c;常用于請求削峰&#xff0c;事務的隊列處理&#xff0c;事件訂閱機制的實現等。 準備工作 創建一個 express.js 項目&#xff08;本文基于evp-express-cli&#xff09;…

【三維編輯】Seal-3D:基于NeRF的交互式像素級編輯

文章目錄 摘要一、引言二、方法2.1.基于nerf的編輯問題概述2.2.編輯指導生成2.3.即時預覽的兩階段學生訓練 三、實驗四、代碼總結 項目主頁: https://windingwind.github.io/seal-3d/ 代碼&#xff1a;https://github.com/windingwind/seal-3d/ 論文: https://arxiv.org/pdf/23…

創建一個Spring Boot項目

安裝所需軟件&#xff1a;首先確保你的計算機上已經安裝了Java JDK和Maven構建工具。你可以從官方網站下載并按照說明進行安裝。 創建一個新的Spring Boot項目&#xff1a;在命令行或終端中使用Maven命令創建一個新的Spring Boot項目。執行以下命令&#xff1a;mvn archetype:…

阿里云輕量應用服務器_2核4G4M_2核2G3M_性能測評

阿里云輕量應用服務器2核2G3M帶寬108元一年&#xff0c;系統盤為50GB高效云盤&#xff1b;輕量服務器2核4G4M帶寬&#xff0c;60GB高效云盤297.98元12個月。目前輕量應用服務器只有2核2G和2核4G有活動&#xff0c;阿里云百科分享阿里云輕量應用服務器入口&#xff1a; 目錄 阿…

【Qt高階】老Qt都不一定清楚的“QObject線程親和性”【2023.08.13】

老Qt都不一定清楚的“線程親和性” 與題目無關 感覺自己還挺2&#xff0c;有粉絲點了那個契約者會給up發個鼓勵的話&#xff0c;我還以為是人私信發的&#xff0c;都挨個感謝了&#xff0c;后來才意識到是系統自動發的&#x1f623;&#x1f623;&#x1f623;。 自上上期視頻對…