并發編程(八股)

概述

并行:同一個時間點,多個線程同時執行
并發:同一個時間段,多個線程交替執行,微觀上是一個一個的執行,宏觀上感覺是同時執行
核心問題:
多線程訪問共享數據存在資源競用問題
不可見性
java內存模型(jmm)
變量數據都存在于主內存里,每個線程還有自己的工作內存(本地內存),規定線程不能直接對主內存中的數據進行操作,只能把主內存的數據加載到自己的工作內存中操作,操作完成后,在寫會主內存
這樣的設計就引發了不可見性,應該線程在自己的工作內存中操作了數據后,另一個線程也在操作,但是不知道數據已經被另一個線程修改了
亂序性
為了優化指令執行,在執行一些等待時間比較長的執行時,可以把其他的一些執行指令提前執行,提高速度
但是在多線程場景下,就會出現問題
非原子性
線程切換執行帶來非原子性
cpu保證原子性執行cpu指令級別的,但是對于高級語言的一條代碼,有時是要拆分為多條指令的,線程在執行到某條執行時操作系統會切換到其他線程去執行,這樣這條高級語言指令執行就是非原子性的
總結:工作內存的緩存導致了不可見性,指令的優化導致了無序性,線程的切換執行導致了非原子性

volatile關鍵字

所修飾的變量在一個工作內存中操作后,底層會將工作內存中的數據同步到其他工作內存中,使其立即可見

  1. 確保多線程操作變量時的可見性,當一個線程修改了變量值,新值會立即對其他線程可見
  2. 防止指令重排序的發生
  3. volatile 無法保證變量操作的原子性

如何保證原子性?

解決非原子性問題,都可以通過加鎖的方式實現,synchronized和ReentrantLock都可以實現
Java還提供了一種方案,在不加鎖的情況下,實現++操作的原子性就是原子類
在java.util.concurrent包下,定義了許多與并發編程相關的處理類,此包一般大家簡稱為JUC
實現方式:采用CAS(比較并交換)思想,當多個線程對同一個內存數據操作時,假設A線程把主內存數據加載到自己的工作內存中,這個工作內存中的值就是預期值,然后在自己的工作內存中操作后,當寫回主內存時,先判斷預期值和主內存的值是否一致,如果一致說明還沒有其他線程修改,直接寫回主內存,一旦預期值和主內存的值不一樣,說明有其他線程已經修改過了,線程A需要重新獲取主內存的值,重新操作,判斷,直到預期值和主內存中的值相同才結束,否則一直判斷
由于采用自旋的方式,使得線程都不會阻塞,一直自旋,適合并發量低的場景,如果并發量過大,線程會一直自旋,會導致CPU開銷大
還會有一個ABA問題,線程A拿到主內存值后,期間有其他線程已經多次修改內存數據,最終又修改到和線程A拿到的值相同,可以通過帶版本號解決

鎖分類

樂觀鎖/悲觀鎖

樂觀鎖是一種不加鎖的實現,例如原子類,認為不加鎖,采用自旋的方式嘗試修改共享數據是不會有問題的,悲觀鎖是一種加鎖的實現,例如synchronized和ReentrantLock認為不加鎖修改共享數據會出問題

可重入鎖

又名遞歸鎖,當同一個線程,獲取鎖進入到外層方法中,可以在內存中可以進入另一個方法中(內層與外層使用同一把鎖)
synchronized和ReentrantLock也是可重入鎖

讀寫鎖

ReentrantReadWriteLock讀寫鎖實現
ReentrantReadWriteLockWriteLock()
ReentrantReadWriteLock.ReadLock()
讀讀不互斥
讀寫互斥
寫寫互斥

分段鎖

將鎖的粒度進一步細化,提高并發效率
hashtable是線程安全的,方法上都加了鎖,假如有兩個線程同時讀,也只能一個一個的讀,并發效率低
concurrentHashMap沒有給方法上加鎖,使用hashtable表中的每個位置上的第一個對象作為鎖對象,這樣可以多個線程對不同位置進行操作,相互不影響,只有對同一個位置操作時,才互斥
有多吧鎖,提高并發操作的效率

自旋鎖

線程嘗試不斷的獲取鎖,當第一次獲取不到時,線程不阻塞,嘗試繼續獲取鎖,有可能后面幾次嘗試后,有其他線程釋放了鎖,此時就可以獲取鎖,當嘗試獲取到一定次數后(默認10次),仍然獲取不到任何鎖,那么可以進入阻塞狀態
synchronized就是自旋鎖
并發量低適合自旋鎖

共享鎖/獨占鎖

共享鎖:可以被多個線程共享,讀寫鎖中的讀鎖就是共享鎖
獨占鎖:一把鎖只能有一個線程使用,讀寫鎖的寫鎖,synronized和reentrantLock都是獨占鎖

公平鎖/非公平鎖

公平鎖:可以按照請求獲得鎖的順序來得到鎖
非公平鎖:不按照請求獲取鎖的順序來得到鎖
synchronized是非公平的
ReentrantLock默認是非公平的,可以通過構造方法去改變成公平鎖

鎖狀態

無鎖

偏向鎖

一段同步代碼塊一直由一個線程執行,那么會在鎖對象中記錄下了線程信息,可以直接會的鎖

輕量級鎖

當鎖狀態為偏向鎖時,此時又有其他線程訪問,鎖狀態升級為輕量級鎖,線程不阻塞,采用自旋方式獲取鎖

重量級鎖

當鎖狀態為輕量級鎖時,如果有大量的線程到來,鎖狀態升級為重量級鎖,自旋的線程會進入阻塞狀態,由操作系統去調度管理

Synchronized

關鍵字,由jvm提供,實現同步,隱式的加鎖和釋放鎖修飾代碼塊和方法,修飾代碼塊時需要我們提供一個同步鎖對象,任意類的對象都可以,但只能是唯一一個,記錄線程有沒有進入到同步代碼塊,修飾方法時,對象是自己提供的,非靜態方法鎖對象默認為this,靜態方法鎖對象為當前的class對象,控制同步是依靠進入和退出監視器對象實現的,如果是同步方法,在指令中會為方法添ACC_SYNCHRONIZED標志,如果是同步代碼塊,在進入到同步代碼塊時,會執行monitorenter,離開同步代碼塊時或出異常時,執行monitorexit,為了提高鎖的獲取與釋放效率在對象頭中記錄鎖狀態,

AQS

抽象同步隊列,是一個實現線程同步的框架,并發包中有很多底層都用到了AQS,通過?FIFO 隊列?和?原子狀態變量(state)?管理線程的阻塞與喚醒,提供了統一的底層實現機制
核心思想:線程競爭資源時,通過 CAS 操作嘗試修改 state 獲取資源,成功則直接執行;失敗則封裝為節點進入隊列等待,通過 LockSupport 實現阻塞 / 喚醒。AQS 支持獨占(如 ReentrantLock)和共享(如 Semaphore)兩種模式,子類只需重寫 tryAcquire/tryRelease 等方法即可快速實現自定義同步器,是構建鎖、信號量等并發工具的高效底層機制

JUC常用類

ConcurrentHashMap

HashMap適合單線程,不允許多個線程同時訪問操作,如果有多線程訪問會報異常
Hashtable是線程安全的 直接給方法加鎖,效率低
ConcurrentHashMap是線程安全的 沒有直接給方法加鎖,用哈希表中每一個位置上的第一個元素作為鎖對象,哈希表的長度是16,那么就有16把鎖對象,鎖住自己的位置即可,這樣如果多個線程操作不同的位置,那么相互不影響,只有多個線程操作同一個位置,才會等待
如果位置上沒有何元素,那么會采用cas機制插入數據到對應位置
hashtable concurrentHashMap 鍵值都不能為空

CopyOnWriteArrlist

ArrayList是單線程場景下使用的,在多線程場景下會報異常
Vector 是線程安全的,在方法上加了鎖,效率低,讀寫用的同一把鎖
CopyOnWriteArrayList? 寫方法上加了鎖(ReentrantLock實現的),寫入數據時,先把圓數組做了一個備份,把要添加的數據寫入到備份數組中,當寫入完成后,在把修改后的數組賦值到原數組中去
給寫加鎖,讀沒有加鎖,讀的效率就變高了,適合寫操作少,讀操作多的場景

CopyOnWriteArraySet

CountDownLatch

線程池

為減少頻繁的創建和銷毀線程
JDk5引入了線程池,建議使用ThreadPoolExecutor類來創建線程池,提高了效率

ThreadPoolExecutor? 構造器的各個參數:
corePoolSize? 核心線程池的線程數量(初始化5)
maximumPoolSize? 線程池中最大線程數量(初始化10)
keepAliveTime? 空閑線程存活時間當核心線程池中的線程足以應付任務時,非核心線程池中的線程在指定空閑時間到期后,會銷毀
unit? 時間單位
workQueue??等待隊列,當核心線程池中的線程都在使用時,會先將等待的線程放到隊列中,如果隊列滿了,才會創建新的線程(非核心線程池中的線程)
threadFactory??線程工廠,用來創建線程池中的數量
handler??拒絕處理任務的策略
四大策略:AbortPolicy? 拋異常
CallRunsPolicy??由提交任務的線程執行,例如在main線程提交,則由main線程執行拒絕任務
DiscardOldestPolicy??丟棄等待時間最長的任務
DiscardPolicy??丟棄最后不能執行的任務

工作流程:

有大量工作任務到來時,先判斷核心線程池中的線程是否都忙著,有空閑的就讓核心線程池中的線程執行任務,沒有空閑的,就判斷等待的隊列是否已滿,如果沒滿,就把任務添加到隊列等待,如果隊列已經滿了,在判斷非核心線程池中的線程是否都忙著,如果有空閑的,,沒滿,就就由非核心的線程池中的線程執行,如果非核心線程池也滿了,就使用對應的拒絕策略處理

提交任務

void ececute 沒有返回值
submit? 有返回值

關閉線程池

shutdown??執行后不再接收任務,會把線程池中和等待隊列中已有的任務執行完后再停止
shutdownNow??立即執行,等待的任務不再執行

ThreadLocal

為每一個線程提供一個變量副本,只在當前線程中使用,相互隔離

實現:為每個Thread創建一個ThreadLocal.ThreadLocalMap threadLocals把變量副本放在ThreadLocal.ThreadLocalMap?中,用ThreadLocal對象統一作為鍵,每一個獲取變量時,先拿到當前線程,拿到線程中的ThreadLocal.ThreadLocalMap?

內存泄漏:對象已經不用了,但是垃圾回收不能回收該對象(例如數據庫連接對象,流對象,socket)
不再使用時調用remove方法,刪除鍵值對,可以避免內存泄漏問題

對象引用:
強引用
Object obj=new Object();強引用
對象如果有強引用關聯,那么肯定是不能被回收的
軟引用
被SoftReference類包裹的對象,當內存充足時,不會被回收,當內存不足時,即使有引用指向,也會被回收
弱引用
被WeakReference類所包裹的對象,只要發生垃圾回收,該類對象都會被回收掉
ThreadLocal被弱引用管理
當發生垃圾回收時,被回收掉,但是value還與外界保持著引用關系,
虛引用
被PhantomReference類包裹的對象,隨時都可以被回收,通過虛引用對象跟蹤對象回收狀態

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

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

相關文章

如何在 Spring Boot 中設計和返回樹形結構的組織和部門信息

如何在 Spring Boot 中設計和返回樹形結構的組織和部門信息 文章目錄如何在 Spring Boot 中設計和返回樹形結構的組織和部門信息1. 需求分析一、數據庫表設計1.1 organization 表設計1.2 department 表設計1.3 模擬數據二、后端設計2.1 實體類設計Organization 實體類Departmen…

Java畢業設計選題推薦 |基于SpringBoot的水產養殖管理系統 智能水產養殖監測系統 水產養殖小程序

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

排序概念、插入排序及希爾排序

一、排序基本概念1.就地排序:使用恒定的額外空間來產生輸出就地排序只是在原數組空間進行排序處理,也就是輸入的數組和得到的數組是同一個2.內部排序和外部排序:待排序數據可以一次性載入到內存中為內部排序,反之數據量過大就是外…

【排序算法】④堆排序

系列文章目錄 第一篇:【排序算法】①直接插入排序-CSDN博客 第二篇:【排序算法】②希爾排序-CSDN博客 第三篇:【排序算法】③直接選擇排序-CSDN博客 第四篇:【排序算法】④堆排序-CSDN博客 第五篇:【排序算法】⑤冒…

Android領域驅動設計與分層架構實踐

引言在Android應用開發中,隨著業務邏輯日益復雜,傳統的MVC或簡單MVP架構往往難以應對。領域驅動設計(Domain-Driven Design, DDD)結合分層架構,為我們提供了一種更系統化的解決方案。本文將探討如何在Android項目中應用DDD原則與分層架構&…

Android12 Framework電話功能UI定制

文章目錄簡介代碼中間按鈕Fragment創建VideoCallFragmentFragment管理添加按鍵掛斷電話功能相關文章簡介 Android版本:12 芯片平臺:展銳 如下圖為通話中的UI,打電話出去時顯示的UI與此也差不多,但來電時UI是不一樣的 這個界面是…

高并發場景下分布式ID生成方案對比與實踐指南

高并發場景下分布式ID生成方案對比與實踐指南 在分布式系統中,唯一且全局有序的ID生成器是很多業務的底層組件。隨著系統并發量不斷攀升,如何在高并發場景下保證ID的唯一性、性能、可用性和可擴展性,成為后端架構師需要重點考慮的問題。本文將…

Emscripten 指南:概念與使用

Emscripten 指南:概念與使用 什么是 Emscripten? Emscripten 是一個開源的編譯器工具鏈,用于將 C/C 代碼編譯成高效的 WebAssembly(Wasm)和 JavaScript。它基于 LLVM 編譯器架構,允許開發者: ?…

使用鏡像網站 打開克隆 GitHub 網站倉庫內容 git clone https://github.com/

GitHub 網站有時因 DNS 解析問題或網絡限制,國內訪問可能會受限。使用鏡像網站打開網站 使用鏡像網站:GitHub 有一些鏡像網站,可替代官網訪問,如https://hub.fastgit.org、https://gitclone.com、https://github.com.cnpmjs.org等…

Linux隨記(二十二)

一、redhat6.5 從openssh5.3 升級到openssh10 - 報錯處理【升級后賬號密碼一直錯誤 和 sshd dead but subsys locked】 虛擬機測試情況 - 正常:情況一、 升級后賬號密碼一直錯誤 情況二、 執行service sshd status出現 sshd dead but subsys locked

機器學習之TF-IDF文本關鍵詞提取

目錄 一、什么是 TF-IDF? 1.語料庫概念理解 二、TF-IDF 的計算公式 1. 詞頻(TF) 2. 逆文檔頻率(IDF) 3. TF-IDF 值 三、關鍵詞提取之中文分詞的實現 四、TF-IDF簡單案例實現 (1)數據集…

Flutter屏幕和字體適配(ScreenUtil)

一、簡介 flutter_screenutil 是一個 Flutter 插件,專門用于處理屏幕適配問題。它簡化了不同設備間尺寸差異的處理,確保你的應用在各種屏幕上都能保持良好的顯示效果。開發者可以通過簡單的調用來設置基于設計圖尺寸的控件寬高和字體大小。 項目地址&a…

mimiconda+vscode

安裝miniconda實現python包管理,并通過vscode進行編寫python代碼 miniconda簡單介紹 Miniconda 是 Anaconda 公司的一個輕量級 Python 發行版本,它包含了最基本的包管理器 conda 和 Python 環境,只帶最核心的組件,沒有額外的大量科…

Windows文件時間修改指南:從手動到自動化

修改文件的時間屬性可以滿足多種需求。比如,它可以幫助整理文件,使得文件按照特定的時間順序排列,有助于更好地管理資料。它的體積真小,才300多KB。能用來調整文件的創建時間、最后訪問和修改時間。文件時間屬性修改_NewFileTime.…

能刷java題的網站

以下是一些適合刷Java題的優質網站,涵蓋從基礎到進階、算法面試及實戰項目等多種需求: ?一、綜合編程練習平臺? ?LeetCode?(leetcode.com) ?特點?:全球最知名的算法題庫,含海量Java題目,分…

掘金數據富礦,永洪科技為山東黃金定制“數智掘金”實戰營

在黃金開采的轟鳴聲中,另一場靜水深流的“掘金行動”正悄然展開。山東黃金集團,這個行業的巨頭,在深挖地層寶藏的同時,也敏銳捕捉到數據洪流中蘊藏的價值富礦。然而,當海量業務數據匯聚,如何從中精準提煉決…

【論文閱讀】BEVFormer論文解析及Temporal Self-Attention、Spatial Cross-Attention注意力機制詳解及代碼示例

BEVFormer: Learning Bird’s-Eye-ViewRepresentation from Multi-Camera Images via Spatiotemporal Transformers|Temporal Self-Attention、Spatial Cross-Attention注意力機制詳解 BEVFormer(Bird’s-Eye-View Former)是一種先進的計算機視覺模型&am…

在 Ubuntu 中docker容器化操作來使用新建的 glibc-2.32

在 Ubuntu 中使用容器化操作來使用新建的 glibc-2.32,可以通過創建自定義 Docker 鏡像來實現。以下是完整的解決方案: 方案 1:創建包含 glibc-2.32 的 Docker 鏡像 1. 創建 Dockerfile dockerfile # 使用 Ubuntu 基礎鏡像 FROM ubuntu:20.04# 安裝編譯依賴 RUN apt-get …

GOOUUU ESP32-S3-CAM 果云科技開發板開發指南(二)(超詳細!)Vscode+espidf 攝像頭拍攝視頻實時傳輸到LCD,文末附源碼

書接上回,上一篇blog是使用esp32s3通過ov2640攝像頭拍攝到一幀照片,并把它保存到了SD卡中,這第二篇就通過LCD將拍攝到的圖片顯示到LCD上,本次分享硬件使用的 ESP32-S3-CAM 果云科技開發板,并且使用了配套的LCD擴展板&a…

攻防世界-ics-05(遠程文件執行)

一.審題大致瀏覽一下網頁,發現就這邊會有東西。看一下源碼會不會有東西或者稍微點擊一下這個頁面的內容看會不會出現東西。點擊了一下這個云平臺設備維護中心發現url變了,是get的方法傳page參數二.嘗試漏洞類型自己這邊試了sql注入發現不是,試…