Java應屆生求職八股(5)---并發編程篇

線程基礎

線程與進程的區別

  • 進程是程序的一次執行過程。它資源分配的單位
  • 線程程序執行的單位

并行和并發的區別

  • 單核CPU下,線程串行。(并發:多線程輪流使用一個或多個CPU)
  • 多核CPU下,每個核都可調度線程。(并行:多CPU同時執行多個線程。

創建線程的方式

  1. 繼承Thread類
  2. 實現Runnable接口
  3. 實現Callable接口
  4. 線程池創建線程
runnable和callable的區別
  • Runnable接口run方法沒有返回值;Callable接口call方法返回值
  • Runnable接口run方法的異常只能內部消化不能上拋;Callable接口call方法允許拋出異常
線程的run()和start()的區別
  • start():用于啟動線程能被調用一次
  • run():封裝要被線程執行的代碼,可以被調用多次
wait()和sleep()方法的區別

1.方法歸屬不同

  • sleep() 是Thread類的靜態方法
  • wait() 是Object類的成員方法,任何對象都有

2.喚醒時機不同

  • 執行 sleep() 的線程會在等待相應毫秒后喚醒
  • wait() 可以被?notify() 喚醒

3.鎖特性不同

  • wait()方法的調用必須先獲取對象的;sleep()不需要
  • wait()執行完會釋放對象鎖;sleep()若在synchronized中執行,不釋放對象鎖

線程的狀態與轉換條件

三個線程如何順序執行

使用線程中的join()方法解決。

t.join():等待線程運行結束。阻塞調用此方法的線程,直到t線程執行完成。

    并發安全

    Synchronized

    實現原理

    基于進入和退出Monitor對象來實現方法同步和代碼塊同步。

    • 方法級的同步是隱式,JVM可以通過?ACC_SYNCHRONIZED 訪問標志區分一個方法是否同步方法。
    • 代碼塊的同步是利用monitorentermonitorexit這兩個字節碼指令。

    底層實現

    synchronized的底層實現是依賴于Java對象頭,以及Monitor對象監視器。

    Monitor監視器鎖有三個重要屬性:_Owner _WaitSet _EntryList

    • _owner指向持有ObjectMonitor對象的線程。
    • 當多個線程同時訪問時,首先會進入 _EntryList 集合等待。
    • 當線程獲取到對象的monitor 后,把monitor中的owner變量設置為當前線程,同時monitor中的計數器count加1。
    • 若線程調用 wait() 方法,將釋放當前持有的monitor,owner變量恢復為null,count自減1,同時該線程進入 _WaitSet集合中等待被喚醒。

    Monitor實現的鎖屬于重量級鎖,于是有了鎖升級,基于對象頭(MarkWord)

    • 最輕程度的鎖為偏向鎖,資源總是由同一線程多次獲得。偏向鎖只依賴于鎖對象,鎖對象在64位虛擬機里由64Bit的Markword來控制,線程獲取鎖時,通過CAS方式將線程ID設置到對象頭里的MarkWord的Thread ID中,線程ID指針在MarkWord中占用54個比特位偏向鎖的標識位為101
    • 當對象進行了hash操作,那么鎖就會失效,因為HashCode在MarkWord中占用31個比特位無鎖的表示位為001
    • 接著被另外的線程所訪問,偏向鎖升級為輕量級鎖,MarkWord中設置指向線程棧的lock record指針。其他線程會自旋嘗試獲取鎖,不會阻塞。輕量級鎖的標識位為000
    • 一旦線程競爭,升級為重量級鎖,其他線程都會被阻塞重量級鎖的標識位為010

    JMM(java內存模型)

    • JMM把內存分為兩塊,一塊是私有線程的工作內存,一塊是所有線程的共享區域(主內存)
    • 線程與線程間相互隔離,交互需通過主內存。

    Volatile關鍵字

    1. 保證線程間的可見性:修飾共享變量,防止編譯器等優化發生,讓線程對共享變量的修改對另一個線程可見。
    2. volatile禁止指令重排序:修飾共享變量會在讀、寫共享變量時加入不同屏障,阻止其他讀寫操作,從而阻止重排序。

    AQS

    全稱為AbstractQueuedSynchronizer(抽象隊列同步器)。它是構建鎖的基礎框架

    • AQS中有個屬性state表示狀態,0為無鎖,1為有鎖。
    • 還維護了一個雙向隊列作為FIFO隊列,其他線程會進入隊列等待,線程釋放鎖時會喚醒隊列中head的元素。

    ReentrantLock(可重入鎖)

    可重入鎖指:調用lock()方法獲取了鎖后,再調用lock(),是會再阻塞的。

    ReentrantLock利用CAS+AQS隊列實現。支持公平鎖非公平鎖

    Synchronized和Lock的區別

    • synchronized是關鍵字,在 jvm 中由c++實現;Lock 是接口,在 jdk 中由 java 實現。
    • synchronized退出鎖時自動釋放;Lock需要調用unlock方法釋放
    • Lock的功能比synchronized,如公平鎖。

    死鎖產生的條件

    互斥,請求保持,不可剝奪、循環等待。

    (一個線程需要同時獲取多把鎖,容易發生死鎖。)

    線程池

    線程池核心參數

    1. 核心線程數
    2. 最大線程數
    3. 生存時間(救急線程的生存時間)
    4. 時間單位
    5. 任務隊列:當沒有空閑核心線程時,新任務到此隊列等待,隊列滿就會創建救急線程。(ArrayBlockingQueue 和 LinkedBlockingQueue)
    6. 線程工廠
    7. 拒絕策略:當所有線程在忙,工作隊列也滿,才會觸發。
    • AbortPolicy:拋出異常,默認策略;
    • CallerRunsPolicy:調用者的線程來執行;
    • DiscardOldestPolicy:丟棄阻塞隊列中最靠前的任務,執行當前任務;
    • DiscardPolicy:丟棄任務。

    如何確定核心線程數

    • IO密集型任務:核心線程數大小設置為2N+1
    • CPU密集型任務(或者高并發、任務執行時間短):核心線程數大小為N+1

    線程池的種類

    1. Executors.newFixedThreadPool():固定大小的線程池,核心線程數與最大線程數相等
    2. Executors.newSingleThreadExecutor():單線程化的線程池,保證任務FIFO執行
    3. Executors.newCachedThreadPool():可緩存的線程池,核心線程數為0
    4. Executors.newScheduledThreadPool():提供了“延遲”和“周期執行”功能

    不推薦用Executors創建線程池

    應該使用7個參數的ThreadPoolExecutor的方式,按需設置核心線程數和最大線程數,避免無限隊列長度,規避OOM

    ThreadLocal

    ThreadLocal是解決線程安全問題的一個操作類,它為每個線程分配一個獨立的內部存儲空間,實現了線程內的資源共享。

    • set(value):設置值。根據當前線程對象,通過getMap()獲取ThreadLocalMap
    • get():獲取值。通過getEntry()獲取ThreadLocalMap中的Entry對象。通過HashCode & (數組長度 - 1) 定位數組下標。
    • remove():清除值。同get()

    ThreadLocal內存泄漏

    強引用:表示一個對象處于有用且必須的狀態,GC無法回收處于強引用的對象,即便出現OOM。

    User user = new User();

    弱引用:表示一個對象處于可能有用但非必須的狀態。GC一旦發現弱引用,會回收相關聯的對象。

    User user = new User();
    WeakReference weakRef = new WeakReference(user);

    每一個Thread維護一個ThreadLocalMap,Entry對象繼承了WeakReference。其中key弱引用的ThreadLocal實例value是強引用的線程變量副本

    避免內存泄漏

    在使用ThreadLocal后主動使用remove()方法釋放key、value。

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

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

    相關文章

    WSL 配置文件 wsl.conf 設置

    WSL .wslconfig 小技巧 要在 WSL(Windows Subsystem for Linux)中增加內存,你需要編輯 WSL 配置文件 wsl.conf 或者直接調整虛擬機的資源限制。 文章目錄WSL .wslconfig 小技巧以下是步驟: 找到或創建 .wslconfig 文件&#xff1…

    9.從零開始寫LINUX內核——設置中斷描述符表

    Linux 0.12 內核中斷描述符表(IDT)完整實現代碼以下是基于 setup 程序擴展的完整代碼,包含中斷描述符表(IDT)的定義、初始化及中斷處理程序,可直接用于實驗驗證:asm/* setup.s —— 4 扇區&…

    手機實時提取SIM卡打電話的信令聲音-當前現狀與思考

    手機實時提取SIM卡打電話的信令聲音-當前現狀與思考 --純手機-無外置配件的方案規劃 上一篇:手機實時提取SIM卡打電話的信令聲音-新的篇章(篇外小結與思考) 下一篇:手機實時提取SIM卡打電話的信令聲音-整體解決方案規劃 一、前言 我們在2024年09月的…

    【車聯網kafka】常用參數及其命令總結(第八篇)

    目錄 1、kafka參數 1.1 、消費者消息批次發送 1.2 、消息大小的配置(環環相扣的消息大小,調整時需要一起調整) 1.3 、消息重試發送冪等 1.4、消息提交 1.5、分區分配策略(自己看的設置) 1.6、文件存儲 2、kafka命令 2.1 常用命令一覽…

    基于Spring Boot 4s店車輛管理系統 租車管理系統 停車位管理系統 智慧車輛管理系統

    🔥作者:it畢設實戰小研🔥 💖簡介:java、微信小程序、安卓;定制開發,遠程調試 代碼講解,文檔指導,ppt制作💖 精彩專欄推薦訂閱:在下方專欄&#x1…

    17.4 合并購物車

    分析 用戶登錄后,將Cookie中的購物車商品合并到redis數據庫中。如果此時redis中已經有相同id的商品,則使用Cookie中的數據覆蓋redis中的數據。 合并功能需要在用戶登錄后實現,但登錄視圖中應避免過多與登錄邏輯無關的邏輯,所以考慮…

    RK3588消費級8K VR一體機 是否有坑?

    ??芯片平臺????定位場景????核心優勢????消費級功能性短板??全志H8/RK3288入門級VR低成本、基礎性能穩定算力弱(4*A55)、無NPU、顯示分辨率僅1080P高通XR1中端VR/AR均衡性能(Adreno 615 GPU)僅WiFi5、續航≤4小時…

    基于Spring Boot校園二手交易平臺系統設計與實現 二手交易系統 交易平臺小程序

    🔥作者:it畢設實戰小研🔥 💖簡介:java、微信小程序、安卓;定制開發,遠程調試 代碼講解,文檔指導,ppt制作💖 精彩專欄推薦訂閱:在下方專欄&#x1…

    Nginx 服務器常用操作

    一. Nginx 常用配置 1. Nginx 總配置文件 nginx 安裝目錄下的 nginx.conf 文件: # 指定 Nginx worker 進程運行的系統用戶 user nginx; # 自動根據 CPU 核心數啟動相應數量的 worker 進程,充分利用多核。 worker_processes auto; # 自動將 worker 進程綁定到特定 …

    PHP官方及第三方下載地址全指南(2025最新版)

    PHP官方及第三方下載地址全指南(2025最新版) 本文整理了PHP官方及主流第三方下載渠道,包含PHP 5.5至8.4各版本的直接下載鏈接,助您快速獲取安全可靠的PHP環境。 一、PHP官方下載渠道 1.1 全球主站下載 網址:https://…

    深度剖析Redisson分布式鎖項目實戰

    今天在練手項目中也是遇到了許多新的技術,其中我認為最深刻的還是Redisson分布式鎖,這里我就結合一下我項目中用到Redisson分布式鎖的代碼來講述一下Redisson分布式鎖,希望可以幫助大家更深刻地理解這項技術。在之前的文章中我已經講過Rediss…

    第四天-創建一個Classic CAN(經典CAN2.0)/CANFD的系統描述ARXML文件

    【ARXML專題】-構建CAN/CANFD通信系統:ARXML實戰指南 汽車神經系統的"高速公路" 想象一輛現代汽車如同人體,電子控制單元(ECU)是器官,而CAN總線就是連接它們的神經系統。在自動駕駛時代,傳統CAN2.0的"鄉間小路"已無法滿足數據傳輸需求,CANFD的"…

    用架構建模工具Sparx EA繪制企業轉型路線圖

    企業數字化轉型面臨諸多挑戰:信息壁壘導致各部門協同困難,資源投入缺乏科學評估,潛在風險難以提前預判。這些問題不僅拖慢轉型進程,還可能引發高昂的試錯成本。 本文將闡述如何運用架構建模工具Sparx EA的核心功能——可視化路線…

    STM32——GPIO

    總 :STM32——學習總綱 參考資料: STM32F1系列參考手冊-V10(中) 一、GPIO簡介 1.1 GPIO 特點 1.2 GPIO 電氣特性* stm32芯片資料STM32F103ZET6(English) 1.3 GPIO 引腳分布 電源引腳:V開頭 晶振引腳: …

    NUX MG-400 吉他效果器功能原理介紹

    NUX MG-400 是一款多功能數字吉他效果器,它的核心原理就是把吉他的模擬信號,通過 A/D 轉換變成數字信號 → 在 DSP 芯片上做建模運算 → 再通過 D/A 轉換還原成模擬信號輸出。 它的硬件 軟件協作設計,基本可以拆成幾個模塊來看: …

    Linux——進程管理和計劃任務管理

    文章目錄前言一、程序與進程的關系1.1 程序與進程的定義1.2 父進程與子進程二、查看進程信息2.1 ps 命令(重點)2.2 動態查看進程信息top命令(重點)2.3 pgrep命令查詢進程信息2.4 pstree命令以樹形結構列出進程信息三、進程的啟動方…

    阿里云TranslateGeneral - 機器翻譯SDK-自己封賬單文件版本—仙盟創夢IDE

    仙盟創夢IDE代碼<?php /*** 阿里云機器翻譯通用版API調用工具* 文檔參考&#xff1a;https://help.aliyun.com/zh/machine-translation/developer-reference/api-alimt-2018-10-12-translategeneral*/ class AliyunTranslate {// 阿里云訪問密鑰private $accessKeyId;priva…

    新字符設備驅動實驗

    經過前兩章實驗的實戰操作&#xff0c;我們已經掌握了 Linux 字符設備驅動開發的基本步驟&#xff0c;字符 設備驅動開發重點是使用 register_chrdev 函數注冊字符設備&#xff0c;當不再使用設備的時候就使用 unregister_chrdev 函數注銷字符設備&#xff0c;驅動模塊加載成功…

    【更新公告】C++算法·線段樹

    之前的線段樹知識都忘了qwq 現在在重新學線段樹 下一篇就是寫線段樹了&#xff0c;例題已經找好了 A了1遍&#xff0c;但是用的玄學代碼ee 下面是更新公告 更新公告 更新模式改為2~3天1篇 但是絕對高質量&#xff01;&#xff01; (平均質量分93夠嗎qwq) 如果例題好找盡量給出2…

    pyqtgraph 庫 右鍵菜單欄插件漢化

    第一步&#xff0c;打開pyqtgraph文件夾。 第二步&#xff1a;打開graphicsItems&#xff0c;將PlotItem和ViewBox中的.py文件中的英文替換為中文&#xff0c;運行軟件即可看到插件右鍵的菜單欄成為中文。 第三步&#xff1a;GraphicsScene中的&#xff0c;等找到相應的右鍵菜單…