面試中的并發編程題(下)

12、synchronizedLock有什么區別

  • 語法層面

    synchronized是關鍵字,源碼在jvm中,用c++實現

    Lock是接口,源碼又jdk提供,用Java實現

    使用synchronized時,退出同步代碼塊鎖會自動釋放,而使用Lock時,需要手動調用unlock方法釋放

  • 功能層面

    二者都是使用悲觀鎖,都具備基本的互斥、同步、鎖重入功能

    Lock提供了許多Synchronized不具備的功能,例如公平鎖、可打斷、可超時、多條件變量

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockRaceExample {private static final Lock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {// 🧍 線程 A:一上來就搶鎖Thread threadA = new Thread(() -> {System.out.println("線程 A 開始搶鎖...");lock.lock();try {System.out.println("線程 A 獲得了鎖!");Thread.sleep(2000);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}, "Thread-A");// main 線程:先睡一下,再搶鎖System.out.println("main 線程準備...");Thread.sleep(100); // main 線程故意延遲// 啟動線程 AthreadA.start();// main 線程再去搶鎖System.out.println("main 線程開始搶鎖...");lock.lock();try {System.out.println("main 線程獲得了鎖!");} finally {lock.unlock();}threadA.join();}
}
  • Lock有適合不同場景的實現,如ReentrantLockReentrantReadWriteLock(讀寫鎖)

  • 性能層面

    在沒有競爭時,synchronized做了很多優化,如偏向鎖、輕量級鎖,性能不賴

    在競爭激烈的時候,Lock的實現通常會提供更好的性能

13、死鎖的條件

這里用我自己的話來舉個例子

就是吃飯的時候你要拿到叉子和刀子才能完成吃飯這個動作,那么現在有線程A和B,線程A首先拿的是刀子然后刀子就會鎖住,然后線程B拿的是叉子然后叉子就會鎖住,那么假如線程A現在又去想要拿到叉子但是現在叉子被鎖著呢,然后線程B就想拿到刀子而刀子也鎖住了,這個時候就會發生死鎖

簡單來說就是線程A持有刀子然后等待線程B釋放叉子,而線程B又在等待線程A釋放刀子

  • 互斥條件(資源一次只能被一個線程占用)

  • 占有并等待(線程已經占有至少一個資源,又等待獲取其他被占用的資源)

  • 不可剝奪(線程持有的資源不能被其他線程或系統強制剝奪,只能有現成自己釋放)

  • 循環等待(存在一組線程,形成首尾相連的等待環路)

死鎖的診斷

1、當程序出現死鎖現象,我們可以使用jdk自帶的工具:jps和jstack

2、jps:輸出JVM中運行的進程狀態信息

3、jstack:查看java進程內線程的堆棧信息,查看日志,檢查是否有死鎖,如果有死鎖現象,需要查看具體代碼后修復

4、可視化工具jconsoleVisualVm也可以檢查死鎖問題

14、ConcurrentHashMap

1、底層數據結構

  • JDK1.7底層采用的是分段的數組+鏈表實現的

  • JDK1.8采用的數據結構跟HashMap1.8的結構一樣,都是數據+鏈表/紅黑二叉樹

2、加鎖的方式

  • JDK1.7采用的是Segment分段鎖,底層采用的是ReentrantLock

  • JDK1.8采用的是CAS添加新節點,采用synchronized鎖定鏈表或紅黑樹的首節點,相對Segment分段鎖粒度更細,性能更好

15、導致并發程序出現問題的原因是什么

并發程序出現問題,主要原因有三個核心:原子性、可見性、有序性

  • 原子性:多個操作未作為一個整體執行,導致中間狀態被其他線程看到。可以加鎖來解決

  • 可見性:線程緩存導致修改未及時同步,可用volatile或同步塊解決

  • 排序性:指令重排序破壞邏輯,volatile可禁止重排

16、說一下線程池的核心參數

new ThreadPoolExecutor(2,                              // corePoolSize5,                              // maximumPoolSize60L,                            // keepAliveTimeTimeUnit.SECONDS,               // unitnew LinkedBlockingQueue<>(10),  // workQueueExecutors.defaultThreadFactory(), // threadFactorynew ThreadPoolExecutor.AbortPolicy() // handler
);
  • corePoolSize:核心線程數目

  • maximumPoolSize:最大線程數目=核心線程數目+救急線程的最大數目

  • keepAliveTime: 生存時間-救急線程的生存時間,生存時間內沒有新任務,此線程資源會釋放

  • unit:時間單位-救急線程的生存時間單位

  • workQueue:當沒有空閑核心線程時,新來任務會加入到此隊列排隊,隊列滿會創建救急線程執行任務

  • threadFactory:線程工廠可以定制線程對象的創建

  • handler:拒絕策略,當所有線程都在繁忙,workQueue也會被放滿時,會觸發拒絕策略

17、線程池中有哪些常見的阻塞隊列

1、ArrayBlockingQueue:基于數組結構的有界阻塞隊列,FIFO

2、LinkedBlockingQueue:基于鏈表結構的有界阻塞隊列,FIFO

3、DelayedWorkQueue:是一個優先級隊列,可以保證每次出隊的任務都是當前隊列中執行時間最靠前的

4、SynchronousQueue:不存儲元素的阻塞隊列,每個插入操作都必須等待一個移出操作

面試官最喜歡考的就是這個ArrayBlockingQueueLinkedBlockingQueue

ArrayBlockingQueue

  • 強制有界

  • 底層是數組

  • 提前初始化Node數組

  • Node需要時提前創建好的

  • 一把鎖

LinkedBlockingQueue

  • 默認無界

  • 底層是鏈表

  • 是懶惰的,創建節點的時候添加數據

  • 入隊會生成新Node

  • 兩把鎖(頭尾)

18、如何確定核心線程數

1、高并發、任務時間執行短——>(CPU核數+1),減少線程上下文切換

2、并發不高、任務執行時間長

  • IO密集型任務——>(CPU核數*2+1)

  • 計算密集型任務——>(CPU核數+1)

3、并發高、業務執行時間長,解決這種類型任務的關鍵不在于線程池而在于整體架構的設計,看看這些業務里面某些數據是否能做緩存是第一步,增加服務器是第二步,然后到時候線程池的配置就看第2個小點

19、線程池的種類有哪些

1、newFixedThreadPool:創建一個定長線程池,可控制線程最大并發數,超出的線程會在隊列中等待

2、newSingleThreadExecutor:創建一個單線程化的線程池,只能用唯一的工作線程來執行任務,保證所有的任務都是按順序執行的

3、newCacheThreadPool:創建一個可緩存的線程池,如果線程長度超過處理需要,就會生成對應的臨時線程如果不用的話也會自己回收

4、newScheduledThreadPool:可以執行延遲任務的線程池,支持定時及周期任務執行

20、為什么不建議用Executors創建線程池

1、FixedThreadPoolSingleThreadPool

允許的請求隊列長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致OOM

2、CacheThreadPool

允許的創建線程數量為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致OOM

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

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

相關文章

Autosar之DCM模塊

一、DCM介紹 DCM(Diagnostic Communication Manager)是AUTOSAR(汽車開放系統架構)基礎軟件BSW中服務層(Service Layer)的核心模塊,其核心功能是為車輛電子控制單元(ECU)提供符合行業標準(如ISO 14229 UDS、ISO 15765 DoCAN、ISO 15031 OBD等)的診斷服務支持,為開發…

HFSS許可證與版本兼容性

在電磁仿真領域&#xff0c;HFSS&#xff08;High Frequency Structure Simulator&#xff09;軟件因其卓越的性能和廣泛的應用而備受贊譽。然而&#xff0c;為了確保用戶能夠充分利用HFSS的功能并獲得流暢的仿真體驗&#xff0c;許可證與版本兼容性成為了不可忽視的重要因素。…

Java有幾種文件拷貝方式,哪一種效率最高?

文章目錄一、Java文件拷貝的5種方式1. 傳統IO流&#xff08;字節流/字符流&#xff09;手動拷貝2. NIO的FileChannel拷貝&#xff08;transferTo/transferFrom&#xff09;3. Java 7的Files.copy()工具類4. 緩沖流&#xff08;BufferedInputStream/BufferedOutputStream&#x…

【前端教程】JavaScript 基礎總結

JavaScript 的三種使用方式 內部引入&#xff08;常用&#xff09;外部引入&#xff08;一個 js 文件可以被多個頁面共同使用&#xff09;行內&#xff08;少用&#xff09; 區別&#xff1a; 內部引入只能夠使用單頁面外部引入可以應用到多個頁面行內是直接在 HTML 標簽內寫&a…

學習-XMind 思維導圖

XMind 是 2006 年誕生的思維導圖軟件&#xff0c;全球超 1 億用戶&#xff0c;能可視化呈現復雜信息&#xff0c;適用于學習、工作場景。它功能全&#xff08;支持多圖表結構&#xff09;、易操作、顏值高、跨平臺且安全&#xff0c;因此受青睞。其界面有菜單欄&#xff08;含各…

Ubuntu下MySQL、MongoDB與Redis:從安裝到協同的完整指南

目錄 一、MySQL&#xff1a;穩定可靠的關系型數據庫 1.1 安裝與配置 1.2 性能優化實戰 二、MongoDB&#xff1a;靈活的文檔數據庫 2.1 安裝與配置 2.2 性能優化策略 三、Redis&#xff1a;高性能內存數據庫 3.1 安裝與配置 3.2 高級應用場景 四、協同實戰&#xff1a…

【傳奇開心果系列】Flet框架帶圖標帶交互動畫的辦公用品費用占比統計餅圖自定義模板

Flet帶圖標帶交互動畫的辦公用品費用占比統計餅圖自定義模板 一、效果展示GIF動圖 二、應用場景介紹 三、 特色說明 四、小結 五、源碼下載地址 一、效果展示GIF動圖 二、應用場景介紹 該應用是一個基于 Flet 框架開發的交互式辦公用品費用占比統計餅圖。適用于以下場景: 企業…

docker鏡像在containerd為底座的k8s中使用

docker鏡像和container鏡像為什么不能直接共通 Docker 鏡像和 containerd 鏡像本質上格式兼容&#xff08;都遵循 OCI 鏡像規范&#xff09;&#xff0c;但默認情況下 “不能互相識別”&#xff0c;核心原因是存儲位置、命名空間和工具鏈的隔離&#xff0c;而非鏡像格式本身的差…

Java-反射機制

在 Java 編程中&#xff0c;“反射” 是一個貫穿基礎與進階的核心概念&#xff0c;它允許程序在運行時動態獲取類的結構、調用方法、操作屬性&#xff0c;甚至創建對象 —— 無需在編譯期明確知道類的具體信息。一、反射是什么&#xff1f;首先明確一個關鍵定義&#xff1a;Jav…

ARM相關的基礎概念和寄存器

目錄 1、機器碼 2、匯編指令 3、匯編指令集 4、架構 5、內核&#xff08;CPU中的核心&#xff09; 6、處理器 7、復雜指令集和精簡指令集 7.1復雜指令集 7.2精簡指令集 7.3修改 8、內核中的寄存器阻值 8.1溜達存儲類型 8.2、AMR處理器&#xff08;內核&#xff09…

PPT處理控件Aspose.Slides教程:在 C# 中將 PPTX 轉換為 Markdown

將您的PowerPoint幻燈片轉換為Markdown格式&#xff0c;使其兼容 AI 技術。在這個人工智能驅動的時代&#xff0c;GPT和Claude等大模型能夠讀取和生成基于 Markdown 的內容。此外&#xff0c;Markdown 還可用于博客文章和文檔。因此&#xff0c;作為一名 .NET 開發人員&#xf…

Python 多進程(multiprocessing)

文章目錄1. 多進程概述1.1. 多進程的概念1.2. 多進程注意事項2. 進程調用方式2.1. Process 類2.1.1. 構造方法2.1.2. 實例方法2.1.3. 屬性2.2. 面向過程2.3. 面向對象3. 進程間通訊3.1. Queues3.2. Pipes3.3. Managers&#xff08;進行共享數據&#xff09;4. 進程同步5. 進程池…

推薦系統王樹森(五)重排多樣性提升

重排01&#xff1a;物品相似性的度量、提升多樣性的方法_嗶哩嗶哩_bilibili github-PPT 前面的討論中提到 在鏈路的最后進行重排&#xff0c;重排要插入廣告和運營筆記&#xff0c;還要做規則打散&#xff0c;提高推薦的豐富性&#xff0c;比如說一個人特別愛看足球&#xff…

Axios多實例封裝

Axios多實例封裝方案 我將為您提供一個完整的Axios多實例封裝方案&#xff0c;包含基礎封裝、多實例管理和使用示例。 設計思路 創建基礎axios實例封裝&#xff0c;支持請求/響應攔截器實現多實例管理器&#xff0c;支持不同API端點配置提供統一的錯誤處理機制支持請求取消功…

為量化從業者提供免費穩定的股票數據源:免費股票數據API獲取實時數據、歷史數據與技術指標(含多語言代碼指南)實例代碼演示與API文檔說明

? 近年來&#xff0c;股票量化分析因其科學、系統的研究方法&#xff0c;日益成為市場熱點。而進入這一領域的首要步驟&#xff0c;正是獲取全面、準確的股票數據——無論是實時交易行情、歷史走勢記錄&#xff0c;還是企業財務與基本面信息&#xff0c;都是支撐量化策略的核心…

[Sync_ai_vid] UNet模型 | 音頻特征提取器(Whisper)

第2章&#xff1a;LatentSync UNet模型 在第1章&#xff1a;唇形同步推理流程中&#xff0c;我們了解到唇形同步推理流程如同電影導演&#xff0c;協調各"專家模塊"生成完美唇形同步視頻。 本章將深入解析這個"工作室"中最核心的專家——LatentSync UNet…

工業級TF卡NAND + 北京君正 + Rk瑞芯微的應用

目錄前言一&#xff1a;操作CS創世 SD NAND的常用命令1.查看SD設備2.掛載分區3.卸載分區4.分區管理5.格式化分區6.簡單讀寫二&#xff1a;SD底層協議簡要介紹三&#xff1a;對CS創世 SD NAND進行讀寫操作的三大方式1. 使用dd命令2. 使用塊設備的標準接口3. 使用ioctl產生系統調…

深入解析Java并發編程與單例模式

目錄 一、調度(四) 1.隨機調度大環境 二、鎖(二) 1.位置 2.無鎖阻塞 3.重入鎖 4.連續鎖 4.1措施 三、線程方法(二) 1.wait 2.notify 3.wait-notify指位后移 3.1可能時再檢查 3.1.1join(二) 3.1.1.1可能時再檢查死亡 四、單例模式 1.實現 1.1private構造器 1…

java通過redis簡單實現分布式鎖

目錄 一、簡介 二、代碼實現 1、maven添加依賴 2、核心邏輯代碼 3、使用方式 三、總結 一、簡介 我們知道在Java中可以通過關鍵字synchronized來防止并發引起的問題&#xff0c;而分布式中就需要考慮分布式鎖了&#xff0c;今天來講一個比較簡單的實現&#xff0c;通過re…

網絡編程--TCP/UDP Socket套接字

網絡編程 程序員主要操作應用層和傳輸層來實現網絡編程&#xff0c;也就是自己寫一個程序&#xff0c;讓這個程序可以使用網絡來通信&#xff0c;這個程序屬于應用層&#xff0c;實現通訊就需要獲取到傳輸層提供的服務 這就需要使用傳輸層提供的api UDP: 無連接&#xff0c;不可…