介紹java中atomic及相關類

文章目錄

      • 一、Atomic 類的核心原理
      • 二、常見 Atomic 類及用法
        • 1. 基本類型原子類
          • (1)`AtomicInteger`(原子更新 int)
          • (2)`AtomicLong`(原子更新 long)
          • (3)`AtomicBoolean`(原子更新 boolean)
        • 2. 引用類型原子類
          • (1)`AtomicReference<V>`(原子更新對象引用)
          • (2)`AtomicStampedReference<V>`(解決 ABA 問題)
          • (3)`AtomicMarkableReference<V>`(標記是否修改)
        • 3. 數組類型原子類
          • (1)`AtomicIntegerArray`(原子更新 int 數組)
          • (2)`AtomicLongArray` 和 `AtomicReferenceArray`
        • 4. 字段更新器(FieldUpdaters)
          • (1)`AtomicIntegerFieldUpdater`(更新對象的 int 字段)
      • 三、Atomic 類的適用場景
      • 四、局限性
      • 總結

Java 中的 java.util.concurrent.atomic 包提供了一組原子操作類,用于實現多線程環境下的無鎖線程安全編程。這些類基于硬件提供的CAS(Compare-And-Swap,比較并交換) 指令實現,避免了傳統鎖機制的性能開銷,適用于簡單值的并發更新場景(如計數器、標志位等)。

一、Atomic 類的核心原理

Atomic 類的線程安全依賴 CAS 操作,其基本邏輯如下:

  1. 讀取當前內存中的值(V)。
  2. 計算目標值(N,基于當前值的更新結果)。
  3. 用 CAS 指令比較內存中的值是否仍為 V
  • 若是,將內存值更新為 N,操作成功。
  • 若否(被其他線程修改),不做操作,重試或放棄(通常會循環重試)。

CAS 是硬件級別的原子操作,無需加鎖即可保證操作的原子性,因此性能優于synchronizedReentrantLock

二、常見 Atomic 類及用法

atomic 包提供了針對不同數據類型的原子類,可分為以下幾類:

1. 基本類型原子類

用于對 intlong 等基本類型進行原子更新。

(1)AtomicInteger(原子更新 int)

核心方法:

  • getAndIncrement():自增 1,返回更新前的值(類似 i++)。
  • incrementAndGet():自增 1,返回更新后的值(類似 ++i)。
  • getAndAdd(int delta):增加指定值,返回更新前的值。
  • compareAndSet(int expect, int update):若當前值等于 expect,則更新為 update,返回是否成功。

示例:

AtomicInteger count = new AtomicInteger(0);// 自增(線程安全)
count.incrementAndGet(); // 結果為 1// 條件更新
boolean success = count.compareAndSet(1, 100); // 成功,返回 true,值變為 100
(2)AtomicLong(原子更新 long)

用法與 AtomicInteger 類似,用于 long 類型的原子操作。在 32 位 JVM 上,long 的非原子操作可能存在拆分風險,AtomicLong 可保證其原子性。

(3)AtomicBoolean(原子更新 boolean)

用于原子更新布爾值,常用 compareAndSet 實現線程安全的開關控制:

AtomicBoolean flag = new AtomicBoolean(false);// 若當前為 false,則更新為 true
if (flag.compareAndSet(false, true)) {System.out.println("執行初始化操作");
}
2. 引用類型原子類

用于原子更新對象引用,支持更復雜的并發場景。

(1)AtomicReference<V>(原子更新對象引用)

可對任意對象引用進行原子操作,例如原子更新用戶對象:

class User {String name;public User(String name) { this.name = name; }
}AtomicReference<User> userRef = new AtomicReference<>(new User("Alice"));// 原子更新用戶(若當前是 Alice,則改為 Bob)
User oldUser = new User("Alice");
User newUser = new User("Bob");
boolean swapped = userRef.compareAndSet(oldUser, newUser); // 成功,返回 true
(2)AtomicStampedReference<V>(解決 ABA 問題)

AtomicReference 存在 ABA 問題(值從 A 變為 B 再變回 A,CAS 會誤認為未修改)。AtomicStampedReference 通過版本號(stamp)解決此問題,每次更新時版本號遞增:

// 初始化:值為 "A",版本號為 0
AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);int[] stampHolder = new int[1];
String current = ref.get(stampHolder); // current = "A", stampHolder[0] = 0// 只有當值為 "A" 且版本號為 0 時,才更新為 "B",版本號+1
boolean success = ref.compareAndSet("A", "B", 0, 1); // 成功
(3)AtomicMarkableReference<V>(標記是否修改)

AtomicStampedReference 類似,但用布爾值(mark)標記是否被修改,而非版本號,適用于只需判斷“是否被修改”的場景。

3. 數組類型原子類

用于原子更新數組中的元素。

(1)AtomicIntegerArray(原子更新 int 數組)
int[] arr = {1, 2, 3};
AtomicIntegerArray atomicArr = new AtomicIntegerArray(arr);// 原子更新索引 1 的元素(加 5)
atomicArr.addAndGet(1, 5); // 數組變為 [1, 7, 3]// 條件更新索引 0 的元素
atomicArr.compareAndSet(0, 1, 10); // 索引 0 的值從 1 變為 10
(2)AtomicLongArrayAtomicReferenceArray

分別用于原子更新 long 數組和對象引用數組,用法與 AtomicIntegerArray 類似。

4. 字段更新器(FieldUpdaters)

用于原子更新對象的非靜態字段(需字段可見性為 volatile),無需修改類定義即可實現原子操作。

(1)AtomicIntegerFieldUpdater(更新對象的 int 字段)

示例:

class Student {volatile int score; // 必須是 volatile 修飾的非靜態字段public Student(int score) { this.score = score; }
}// 創建更新器(指定類和字段名)
AtomicIntegerFieldUpdater<Student> updater = AtomicIntegerFieldUpdater.newUpdater(Student.class, "score");Student student = new Student(80);
// 原子更新 score 字段(加 10)
updater.addAndGet(student, 10); // score 變為 90

類似的還有 AtomicLongFieldUpdaterAtomicReferenceFieldUpdater,用于更新 long 字段和對象字段。

三、Atomic 類的適用場景

  1. 計數器:如接口調用次數、并發任務數統計(AtomicIntegerAtomicLong)。
  2. 標志位:如線程安全的開關控制(AtomicBoolean)。
  3. 無鎖數據結構:如實現非阻塞隊列、棧等(基于 AtomicReference)。
  4. 樂觀鎖場景:通過版本號控制(AtomicStampedReference)實現并發更新。

四、局限性

  1. 僅支持簡單操作:適合單一變量的原子更新,復雜邏輯(如多變量聯動)仍需鎖機制。
  2. 可能導致自旋消耗:CAS 失敗時會循環重試,高并發下可能浪費 CPU 資源。
  3. 無法解決所有并發問題:如需要互斥的場景(如“檢查-修改-操作”三步原子性),可能仍需鎖。

總結

atomic 包提供的原子類通過 CAS 操作實現了高效的線程安全,適合簡單值的并發更新場景,性能優于傳統鎖機制。但需注意其局限性:僅適用于單一變量操作,復雜場景仍需結合鎖或其他并發工具。實際開發中,應根據業務復雜度選擇合適的并發方案。

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

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

相關文章

消費級顯卡分布式智能體協同:構建高性價比醫療AI互動智能體的理論與實踐路徑

摘要: 本文系統探討了基于消費級顯卡集群(NVIDIA 30/40系列)的分布式小模型(1.5B-7B)協同機制,構建醫療互動智能網的理論基礎與實踐路徑。文章從醫療AI的特殊性出發,提出“異構智能體協同計算”范式,通過模型分片、動態任務調度、聯邦學習等核心技術,解決醫療場景中數…

C++進階:特殊類

目錄1. 不能被拷貝的類2. 只能在堆上創建的類3. 只能在棧上創建的類4. 不能被繼承的類5. 類的設計模式&#xff08;單例模式&#xff09;5.1 餓漢模式設計5.2 懶漢模式設計特殊類的概念&#xff1a; 特殊類是一些具有特殊行為、用途&#xff0c;用特殊方法設計而出的類。1. 不…

【論文閱讀】基于卷積神經網絡和預提取特征的肌電信號分類

Myoelectric Signal Classi?cation Using Convolutional Neural Networks with Pre-Extracted Features 原文&#xff1a;DOI: 10.1109/ICICS55353.2022.9811218 2022 翻譯&#xff1a;靠岸學術 目錄 摘要 1引言 2背景 A. 卷積神經網絡 B. 特征工程 3材料與方法 A. CN…

珠海社保繳費記錄如何打印

珠海社保掌上辦&#xff08;微信小程序&#xff09; 進入“珠海社保掌上辦”—“資料打印”— 選擇養老工傷失業個人繳費證明&#xff0c;可選擇 全部繳費記錄打印或自選時段打印&#xff1a; 長按圖片保存后打印。

AM32電調學習-使用Keil編譯uboot

目前的AM32的APP固件包含了keil工程&#xff0c;但是uboot還沒看到&#xff0c;對于習慣使用keil的新用戶&#xff0c;調試起來會有些不習慣&#xff0c;本文將簡單描述怎么新建一個keil的uboot工程&#xff0c;以AT32F421為例。一、新建目錄新建一個目錄Keil_Projects二、新建…

【大文件上傳】分片上傳+斷點續傳+Worker線程計算Hash

/*** 文件分片上傳管理器* 提供文件分片、哈希計算、并發上傳和斷點續傳功能*/ class FileChunkUploader {/*** 構造函數* param {File} file - 要上傳的文件對象* param {Object} options - 配置選項* param {number} [options.chunkSize5MB] - 每個分片的大小&#xff08;字節…

-bash: ./restart.sh: /bin/bash^M: 壞的解釋器: 沒有那個文件或目錄

這是典型的Windows換行符&#xff08;CRLF&#xff09;導致的腳本不能在Linux/Unix環境下正常執行的問題。Linux 期望的是 LF (\n)&#xff0c;而 Windows 是 CRLF (\r\n)&#xff0c;所以腳本文件的第一行解釋器路徑后多了一個不可見的 ^M&#xff08;回車符&#xff09;&…

芯伯樂1MHz高頻低功耗運放芯片MCP6001/2/4系列,微安級功耗精密信號處理

前言在工業控制、通信設備、家用電器等領域&#xff0c;信號處理是核心環節之一&#xff0c;其中運算放大器&#xff08;運放&#xff09;是實現信號處理的核心器件&#xff0c;其選型參數直接決定了信號鏈路的性能和輸出信號的質量&#xff0c;是確保信號正常、精確輸出的關鍵…

智能的數學原理

智能的數學原理可以分成幾個層次來看——從最底層的數學基礎&#xff0c;到支撐“智能”表現的數學模型&#xff0c;再到連接數學與現實認知的理論框架。 分成 五個核心板塊 來梳理&#xff1a;1. 信息與表示的數學 智能的第一步是“能表示信息”&#xff0c;這涉及&#xff1a…

FPGA即插即用Verilog驅動系列——SPI發送模塊

實現功能&#xff1a;按字節以spi模式3發送數據&#xff0c;如果要stm32接收&#xff0c;請在cubemx中將對應的spi接口設置為模式3&#xff0c;詳情見代碼開頭注釋// spi_byte_master.v // 經過優化的SPI主設備模塊&#xff0c;每次使能發送一個字節。 // 它實現了SPI模式3 (CP…

C++ 排序指南

在 C 中&#xff0c;std::sort 是一個非常強大且常用的函數&#xff0c;用于對容器或數組中的元素進行排序。它定義在 <algorithm> 頭文件中。 std::sort 的基本語法 std::sort 的基本語法有以下幾種形式&#xff1a;默認升序排序&#xff1a; std::sort(first, last);fi…

RS232串行線是什么?

RS232串行線是什么&#xff1f;RS232串行線是一種用于串行通信的標準化接口&#xff0c;廣泛應用于早期計算機、工業設備、儀器儀表等領域的短距離數據傳輸。以下是其核心要點解析&#xff1a;1. 基本定義 全稱&#xff1a;RS232&#xff08;Recommended Standard 232&#xff…

k8s-scheduler 解析

學習文檔 官網的k8s上關于scheduler的文檔基本可以分為這兩部分 介紹 scheduler 的基本概念 介紹 scheduler 的配置 KubeSchedulerConfiguration 的參數 介紹 scheduler 的命令行參數 調度框架解析 Scheduling-framework 解析 kube-scheduler 選擇 node 通過下面這兩步…

前端簡歷1v1修改: 優化項目經驗

今天有人找我優化前端簡歷&#xff0c;分享一下如何優化項目經驗描述。這是修改前的版本&#xff1a;項目為Web前端開發&#xff0c;但描述為APP應用&#xff0c;包含某某功能。起初我感到困惑&#xff0c;因為前端技術棧使用Vue&#xff0c;為何項目類型是APP&#xff1f;后來…

K8S企業級應用與DaemonSet實戰解析

目錄 一、概述 二、YAML文件詳解 三、企業應用案例 3.1 環境準備 3.2 擴縮容 3.3 滾動更新 3.4 回滾 四、自定義更新策略 4.1類型 4.2 設置方式 4.3 配置案例 一、 DaemonSet 概述 DaemonSet 工作原理 Daemonset 典型的應用場景 DaemonSet 與 Deployment 的區別…

Celery在Django中的應用

Celery在Django中的應用一、項目配置二、異步任務2.1 普通用法2.1.1 通過delay2.1.2 通過apply_async2.2 高級用法2.2.1 任務回調&#xff08;Callback&#xff09;2.2.2 任務鏈&#xff08;Chaining&#xff09;2.2.3 任務組&#xff08;Group&#xff09;2.2.4 任務和弦&…

DeepSeek生成的高精度大數計算器

# 高精度計算器&#xff08;精確顯示版&#xff09;1. **精確顯示優化**&#xff1a;- 新增print_mpfr()函數專門處理MPFR數值的打印- 自動移除多余的尾隨零和小數點- 確保所有浮點結果都以完整十進制形式顯示&#xff0c;不使用科學計數法2. **浮點精度修復**&#xff1a;- 所…

08--深入解析C++ list:高效操作與實現原理

1. list介紹1.1. list概述template < class T, class Alloc allocator<T> > class list;Lists are sequence containers that allow constant time insert and erase operations anywhere within the sequence, and iteration in both directions.概述&#xff1…

GraphQL從入門到精通完整指南

目錄 什么是GraphQLGraphQL核心概念GraphQL Schema定義語言查詢(Queries)變更(Mutations)訂閱(Subscriptions)Schema設計最佳實踐服務端實現客戶端使用高級特性性能優化實戰項目 什么是GraphQL GraphQL是由Facebook開發的一種API查詢語言和運行時。它為API提供了完整且易于理…

使用 Dockerfile 與 Docker Compose 結合+Docker-compose.yml 文件詳解

使用 Dockerfile 與 Docker Compose 結合的完整流程 Dockerfile 用于定義單個容器的構建過程&#xff0c;而 Docker Compose 則用于編排多個容器。以下是結合使用兩者的完整方法&#xff1a; 1. 創建 Dockerfile 在項目目錄中創建 Dockerfile 定義應用鏡像的構建過程&#xff1…