Java高頻面試之并發編程-27

hello啊,各位觀眾姥爺們!!!本baby今天又來報道了!哈哈哈哈哈嗝🐶

面試:詳細說說AtomicInteger 的原理


AtomicInteger 的原理詳解
AtomicInteger 是 Java 并發包 (java.util.concurrent.atomic) 中的原子類,用于實現 線程安全的整型變量操作(如 i++),其核心原理基于 CAS(Compare and Swap) 無鎖算法和 volatile 可見性。以下是其實現原理的詳細分析:


1. 核心設計

(1) 依賴的底層技術
  • CAS 操作:通過 sun.misc.Unsafe 類調用 CPU 的原子指令(如 CMPXCHG),實現無鎖的原子更新。
  • volatile 變量:內部值 valuevolatile 修飾,保證多線程間的可見性(直接讀寫主內存)。
(2) 類結構關鍵代碼
public class AtomicInteger extends Number implements java.io.Serializable {private static final long serialVersionUID = 6214790243416807050L;// 使用 Unsafe 類操作底層 CASprivate static final Unsafe unsafe = Unsafe.getUnsafe();private static final long valueOffset; // value 字段的內存偏移量static {try {// 獲取 value 字段在對象內存中的偏移量valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));} catch (Exception ex) { throw new Error(ex); }}private volatile int value; // 實際存儲值的 volatile 變量public AtomicInteger(int initialValue) {value = initialValue;}
}

2. 關鍵方法實現原理

(1) incrementAndGet():原子自增
public final int incrementAndGet() {return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}// Unsafe 類的實現
public final int getAndAddInt(Object o, long offset, int delta) {int v;do {v = getIntVolatile(o, offset); // 讀取當前值} while (!compareAndSwapInt(o, offset, v, v + delta)); // CAS 更新return v;
}

步驟

  1. 讀取當前值:通過 getIntVolatile 讀取 value 的當前值(volatile 保證可見性)。
  2. CAS 更新:嘗試用 compareAndSwapIntvaluev 更新為 v + delta
  3. 失敗重試:若 CAS 失敗(值已被其他線程修改),循環重試直到成功。
(2) compareAndSet():CAS 核心方法
public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
  • 若當前值等于 expect,則將其更新為 update,返回 true;否則返回 false
(3) get()set():直接訪問 volatile 變量
public final int get() {return value; // 直接讀取 volatile 變量,保證可見性
}public final void set(int newValue) {value = newValue; // 直接寫入 volatile 變量
}

3. 無鎖設計的優勢

(1) 高性能
  • 無阻塞:線程通過自旋(循環重試)而非阻塞等待,減少上下文切換開銷。
  • 低競爭時高效:在低并發場景下,CAS 成功率極高,性能遠超 synchronizedReentrantLock
(2) 避免死鎖
  • 無鎖機制天然避免死鎖,因為沒有線程會持有鎖不放。

4. 局限性及應對

(1) ABA 問題
  • 問題描述:若變量的值從 A 改為 B 后又改回 A,CAS 無法感知中間變化。
  • 解決方案:使用 AtomicStampedReferenceAtomicMarkableReference,通過版本號標記狀態。
    AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(0, 0);
    ref.compareAndSet(0, 1, 0, 1); // 檢查值 + 版本號
    
(2) 自旋開銷
  • 問題:高并發下 CAS 失敗率高,線程長時間自旋浪費 CPU。
  • 優化策略
    • 退避算法:失敗后等待一段時間再重試(如 Thread.yield())。
    • 結合鎖機制:在自旋一定次數后轉為阻塞鎖。
(3) 僅支持單一變量
  • 問題:無法原子更新多個變量(如 i++j++ 需同時保證原子性)。
  • 解決方案
    • 使用 AtomicReference 封裝多個變量為一個對象。
    • 對復合操作使用鎖(如 synchronized)。

5. 性能對比

AtomicInteger vs synchronized vs ReentrantLock
場景AtomicIntegersynchronizedReentrantLock
低競爭極快(無鎖自旋)較快(偏向鎖優化)較快(CAS 嘗試)
高競爭較差(自旋開銷大)較差(線程阻塞頻繁)較差(CAS 競爭激烈)
復合操作不支持支持支持

6. 應用場景

  • 計數器:如統計請求量、在線人數。
  • 狀態標志:如開關狀態的原子切換。
  • 序列生成:生成唯一遞增 ID。

總結

AtomicInteger 通過 CAS + volatile 實現了無鎖的線程安全操作:

  1. CAS:保證原子性,避免鎖開銷。
  2. volatile:保證可見性,確保線程讀取最新值。
  3. 自旋重試:在競爭不激烈時高效,高競爭時需結合退避策略。

你想要的技術資料我全都有:https://pan.q刪掉漢子uark.cn/s/aa7f2473c65b
在這里插入圖片描述

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

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

相關文章

冒險島的魔法果實-多重背包

問題描述 在冒險島的深處&#xff0c;小萌探索到了一個傳說中的魔法果實園。這里滿是各種神奇的魔法果實&#xff0c;吃了可以增加不同的魔法能量。 小萌想帶一些魔法果實回去&#xff0c;但是他的背包空間有限。看著這些琳瑯滿目的魔法果實&#xff0c;小萌很是糾結&#xf…

atomicity of memory accesses

文章目錄 atomicity of memory accesses? 正確認識原子性的邊界對于 **Load**&#xff1a;? 正確的原子性邊界是&#xff1a;對于 **Store**&#xff1a;? 正確的原子性邊界是&#xff1a; &#x1f504; 修正原文中的說法&#xff08;對照分析&#xff09;? 原子性邊界最終…

VScode安裝配置PYQT6

開始是準備安裝PYQT5的&#xff0c;但是安裝不下去&#xff0c;就改成安裝PYQT6 一.安裝pyqt5&#xff0c;成功。 c:\PYQT>pip install pyqt5 Defaulting to user installation because normal site-packages is not writeable Collecting pyqt5 Downloading PyQt5-5.15.…

SpringBoot使用oshi獲取服務器相關信息

概念 OSHI是Java的免費基于JNA的&#xff08;本機&#xff09;操作系統和硬件信息庫。它不需要安裝任何其他本機庫&#xff0c;并且旨在提供一種跨平臺的實現來檢索系統信息&#xff0c;例如操作系統版本&#xff0c;進程&#xff0c;內存和CPU使用率&#xff0c;磁盤和分區&a…

Spring Boot 3 集成 MyBatis 連接 MySQL 數據庫

Spring Boot 3 集成 MyBatis 連接 MySQL 數據庫的步驟&#xff1a; 以下是集成 Spring Boot 3、MyBatis、HikariCP 連接池并操作 MySQL 數據庫的完整步驟和代碼&#xff1a; 一、創建 Spring Boot 項目 添加以下依賴&#xff1a; <dependencies><!-- Spring Web --…

基于React + FastAPI + LangChain + 通義千問的智能醫療問答系統

&#x1f4cc; 文章摘要&#xff1a; 本文詳細介紹了如何在前端通過 Fetch 實現與 FastAPI 后端的 流式響應通信&#xff0c;并支持圖文多模態數據上傳。通過構建 multipart/form-data 請求&#xff0c;配合 ReadableStream 實時讀取 AI 回復內容&#xff0c;實現類似 ChatGPT…

YOLOv8 升級之路:主干網絡嵌入 SCINet,優化黑暗環境目標檢測

文章目錄 引言1. 低照度圖像檢測的挑戰1.1 低照度環境對目標檢測的影響1.2 傳統解決方案的局限性2. SCINet網絡原理2.1 SCINet核心思想2.2 網絡架構3. YOLOv8與SCINet的集成方案3.1 總體架構設計3.2 關鍵集成代碼3.3 訓練策略4. 實驗結果與分析4.1 實驗設置4.2 性能對比4.3 可視…

所有的Linux桌面環境

Linux操作系統提供了多種桌面環境&#xff0c;每種都有其獨特的特點和適用場景。以下是一些常見的Linux桌面環境&#xff1a; 輕量級桌面環境 Xfce&#xff1a;廣泛使用的輕量級桌面環境&#xff0c;適合資源有限的設備。Xfce 4.18帶來了性能改進和新功能&#xff0c;如Thuna…

@component、@bean、@Configuration的區別

詳細解析Spring框架中這三個最核心、也最容易混淆的注解&#xff1a;Component、Bean和Configuration。 為了快速理解&#xff0c;我們先看一個總結性的表格&#xff1a; 注解應用級別作用使用場景Component類級別將類標識為Spring組件&#xff0c;讓Spring自動掃描并創建實例…

Android多媒體——音/視同步數據處理(二十)

在多媒體播放過程中,音頻數據的處理不僅要保證其解碼和輸出的連續性,還需要與視頻幀保持時間上的嚴格對齊,以實現良好的觀看體驗。Android 多媒體框架中的 NuPlayerRenderer 是負責最終渲染音視頻數據的核心組件之一。 一、Audio數據處理 NuPlayerRenderer 是 Android 原生…

MYSQL 使用命令mysqldump備份數據庫的時候需要用戶具備什么權限

背景 之前都是使用數據庫root用戶備份數據庫&#xff0c;沒有權限問題&#xff0c;今天使用一個數據庫基本用戶備份數據庫&#xff0c;提示一直沒有權限&#xff0c;提示的很明顯 mysqldump: Error: Access denied; you need (at least one of) the PROCESS privilege(s) for …

WebRTC源碼線程-1

1、概述 本篇主要是簡單介紹WebRTC中的線程&#xff0c;WebRTC源碼對線程做了很多的封裝。 1.1 WebRTC中線程的種類 1.1.1 信令線程 用于與應用層的交互&#xff0c;比如創建offer&#xff0c;answer&#xff0c;candidate等絕大多數的操作 1.1.2 工作線程 負責內部的處理邏輯&…

spring:使用標簽xml靜態工廠方法獲取bean

在spring可以直接通過配置文件獲取bean對象&#xff0c;如果獲取的bean對象還有若干設置&#xff0c;需要自動完成&#xff0c;可以通過工廠方法獲取bean對象。 靜態工廠類&#xff0c;其中InterfaceUserDao和InterfaceUserService都是自定義的接口&#xff0c;可以自己替換。…

linux 用戶態時間性能優化工具perf/strace/gdb/varlind/gprof

1. perf top -g或者top分析卡頓(cpu占用比較高的函數) gdb 是 GNU 調試器,可以用于分析程序的時間性能。雖然 info time 不是直接用于性能分析的命令,但 gdb 提供了與時間相關的功能,例如通過 timer 命令設置計時器或通過 info proc 查看進程的時間信息。 #include <…

客戶端和服務器已成功建立 TCP 連接【輸出解析】

文章目錄 圖片**1. 連接狀態解析****第一條記錄&#xff08;服務器監聽&#xff09;****第二條記錄&#xff08;客戶端 → 服務器&#xff09;****第三條記錄&#xff08;服務器 → 客戶端&#xff09;** **2. 關鍵概念澄清****(1) 0.0.0.0 的含義****(2) 端口號的分配規則** *…

Win系統下的Linux系統——WSL 使用手冊

我們在復現一些項目的時候&#xff0c;有些依賴包只能在 linux 環境下使用&#xff0c;還不打算使用遠程服務器&#xff0c;那么此時我們可以使用 WSL 創建一個 ubutu 系統&#xff0c;在這個系統里創建虛擬環境、下載依賴包。然后&#xff0c;我們就可以在 windows 下的 vscod…

電腦同時連接內網和外網的方法,附外網連接局域網的操作設置

對于工作一般都設置在內網網段中&#xff0c;而同時由于需求需要連接外網&#xff0c;一般只能通過內網和外網的不斷切換進行設置&#xff0c;如果可以同時連接內網和外網會更加便利&#xff0c;同時連接內網和外網方法具體如下。 一、電腦怎么弄可以同時連接內網和外網&#…

C++11:原子操作與內存順序:從理論到實踐的無鎖并發實現

文章目錄 0.簡介1.并發編程需要保證的特性2.原子操作2.1 原子操作的特性 3.內存順序3.1 順序一致性3.2 釋放-獲取&#xff08;Release-Acquire)3.3 寬松順序&#xff08;Relaxed)3.4 內存順序 4.無鎖并發5. 使用建議 0.簡介 在并發編程中&#xff0c;原子性、可見性和有序性是…

oracle 歸檔日志與RECOVERY_FILE_DEST 視圖

1. RECOVERY_FILE_DEST 視圖的作用 RECOVERY_FILE_DEST 是 Oracle 數據庫用于 管理快速恢復區&#xff08;Fast Recovery Area, FRA&#xff09; 的一個視圖。FRA 是 Oracle 提供的一種集中存儲恢復相關文件&#xff08;如歸檔日志、備份文件、閃回日志等&#xff09;的區域。…

零基礎玩轉物聯網-串口轉以太網模塊如何快速實現與MQTT服務器通信

目錄 1 前言 2 環境搭建 2.1 硬件準備 2.2 軟件準備 2.3 驅動檢查 3 MQTT服務器通信配置與交互 3.1 硬件連接 3.2 開啟MQTT服務器 3.3 打開配置工具讀取基本信息 3.4 填寫連接參數進行連接 3.5 通信測試 4 總結 1 前言 MQTT&#xff1a;全稱為消息隊列遙測傳輸協議&#xff08;…