一個類有一個全局變量 m,多線程對它進行增加操作,如何保證線程安全?

一個類有一個全局變量 m,多線程對它進行增加操作,如何保證線程安全?

在多線程環境下對共享變量進行修改時,確保線程安全的關鍵是保證操作的原子性、可見性和有序性。以下是針對全局變量 m 的多線程自增操作的線程安全解決方案:

1. 使用 synchronized 關鍵字(悲觀鎖)

public class Counter {private static int m = 0;// 實例方法同步(鎖住當前實例)public synchronized void increment() {m++;}// 靜態方法同步(鎖住類的 Class 對象)public static synchronized void staticIncrement() {m++;}
}

特點

  • 簡單直接,但并發性能較低(鎖粒度較大)。
  • 適用于低競爭場景。

2. 使用 ReentrantLock(顯式鎖)

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Counter {private static int m = 0;private static final Lock lock = new ReentrantLock();public static void increment() {lock.lock();try {m++;} finally {lock.unlock();}}
}

特點

  • 更靈活(支持嘗試鎖、可中斷鎖等),但需手動管理鎖的釋放。
  • 適用于需要細粒度控制的場景。

3. 使用原子類 AtomicInteger(無鎖,CAS 實現)推薦!

import java.util.concurrent.atomic.AtomicInteger;public class Counter {private static final AtomicInteger m = new AtomicInteger(0);public static void increment() {m.incrementAndGet(); // 原子性自增}
}

特點

  • 基于 CAS(Compare and Swap)實現無鎖并發,性能高。
  • 適用于高并發場景(如計數器、累加器)。

5. 使用 LongAdder(高并發優化)

import java.util.concurrent.atomic.LongAdder;public class Counter {private static final LongAdder m = new LongAdder();public static void increment() {m.increment(); // 分段累加,減少競爭}public static long get() {return m.sum();}
}

特點

  • 在極高并發場景下性能優于 AtomicInteger,但讀取最終結果時需調用 sum()
  • 適用于寫多讀少的場景(如統計點擊數)。

關鍵對比

方法

原理

性能

適用場景

synchronized

悲觀鎖

低-中

低競爭、簡單同步

ReentrantLock

顯式鎖

需要靈活控制鎖

AtomicInteger

CAS 無鎖

高并發、簡單原子操作

LongAdder

分段 CAS

極高

超高并發寫、最終一致性讀

為什么 volatile 不能單獨解決自增線程安全?

volatile 僅保證:

  1. 可見性:線程修改后其他線程立即可見新值。
  2. 有序性:禁止指令重排序優化。

m++ 是非原子操作(包含讀、改、寫三步),多個線程可能同時讀到相同的舊值并覆蓋寫入,導致結果錯誤。例如:

Thread1: 讀取 m=5 → 計算 5+1=6 → 準備寫入 6
Thread2: 讀取 m=5 → 計算 5+1=6 → 寫入 6
最終結果 m=6(實際應為 7)

最佳實踐

  1. 優先選擇原子類(如 AtomicIntegerLongAdder),兼顧性能和易用性。
  2. 若需復雜同步邏輯(如條件等待),使用 ReentrantLock
  3. 避免過度依賴 synchronized,尤其是在高并發場景下。

通過合理選擇同步機制,可以確保線程安全的同時最大化性能。

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

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

相關文章

CSS關系選擇器詳解

CSS關系選擇器詳解 學習前提什么是關系選擇器?后代選擇器(Descendant Combinator)語法示例注意事項 子代選擇器(Child Combinator)語法示例注意事項 鄰接兄弟選擇器(Adjacent Sibling Combinator&#xff0…

【基于SprintBoot+Mybatis+Mysql】電腦商城項目之用戶注冊

🧸安清h:個人主頁 🎥個人專欄:【計算機網絡】【Mybatis篇】 🚦作者簡介:一個有趣愛睡覺的intp,期待和更多人分享自己所學知識的真誠大學生。 目錄 🎯項目基本介紹 🚦項…

Microsoft Power BI:融合 AI 的文本分析

Microsoft Power BI 是微軟推出的一款功能強大的商業智能工具,旨在幫助用戶從各種數據源中提取、分析和可視化數據,以支持業務決策和洞察。以下是關于 Power BI 的深度介紹: 1. 核心功能與特點 Power BI 提供了全面的數據分析和可視化功能&…

電控三周速成計劃參考

第1周:基礎搭建與GPIO控制 學習目標:建立開發環境,掌握最基礎的硬件控制能力 每日學習(2-3小時): 環境搭建(2天) 安裝Keil MDK-ARM STM32CubeMX使用CubeMX創建第一個工程&#xf…

[SAP ABAP] 在ABAP Debugger調試器中設置斷點

在命令框輸入/H,點擊回車以后,調試被激活,點擊觸發任意事件進入ABAP Debugger調試器界面 點擊按鈕,可以在Debugger調試器中新增臨時斷點 我們可以從ABAP命令、方法、功能、表單、異常、消息、源代碼等多個維度在Debugger調試器中設…

【NEXT】網絡編程——上傳文件(不限于jpg/png/pdf/txt/doc等),或請求參數值是file類型時,調用在線服務接口

最近在使用華為AI平臺ModelArts訓練自己的圖像識別模型,并部署了在線服務接口。供給客戶端(如:鴻蒙APP/元服務)調用。 import核心能力: import { http } from kit.NetworkKit; import { fileIo } from kit.CoreFileK…

RssWebAll:抓取任意網頁的內容生成 RSS 訂閱源

RssWebAll:抓取任意網頁的內容生成 RSS 訂閱源 RssWebAll 是一個強大的工具,可以幫助用戶抓取任意網頁的內容,并生成相應的 RSS 訂閱源,讓用戶隨時隨地獲取他們感興趣的內容更新。 功能亮點 簡單易用:所見即所得&…

從一到無窮大 #43:Presto History Based Optimizer,基于PlanNode粒度統計的查詢計劃選擇策略

本作品采用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。 本作品 (李兆龍 博文, 由 李兆龍 創作),由 李兆龍 確認,轉載請注明版權。 文章目錄 引言MotivationArchitectureHBO ScenarioExperiments結束語 引言 過年回家這件事在摯…

【C++】繼承(下)

大家好,我是蘇貝,本篇博客帶大家了解C的繼承(下),如果你覺得我寫的還不錯的話,可以給我一個贊👍嗎,感謝?? 目錄 5.繼承與友元6.繼承與靜態成員7.復雜的菱形繼承及菱形虛擬繼承8.繼…

項目開發實踐——基于SpringBoot+Vue3實現的在線考試系統(九)(完結篇)

文章目錄 一、成績查詢模塊實現1、學生成績查詢功能實現1.1 頁面設計1.2 前端頁面實現1.3 后端功能實現2、成績分段查詢功能實現2.1 頁面設計2.2 前端頁面實現2.3 后端功能實現二、試卷練習模塊實現三、我的分數模塊實現1、 頁面設計2、 前端頁面實現3、 后端功能實現四、交流區…

【流媒體】搭建流媒體服務器

搭建Windows Nginx服務器 搭建 下載nginx工具包解壓至本地,并在cmd窗口中切換至nginx所在的本地目錄修改 conf/nginx.conf 文件,更改其端口號 server中的 listen的端口號從 80改為 8080,因為80經常被其他服務占用,導致無法打開 …

攜程Java開發面試題及參考答案 (200道-下)

insert 一行數據的時候加的是什么鎖?為什么? 在 MySQL 中,當執行 INSERT 操作插入一行數據時,加鎖的情況會因存儲引擎和具體的事務隔離級別而有所不同。一般來說,在 InnoDB 存儲引擎下,INSERT 操作加的是行級排他鎖(Row Exclusive Lock),以下詳細說明原因。 行級排他…

洛谷P11655「FAOI-R5」Lovely 139

P11655「FAOI-R5」Lovely 139 題目背景 Update:數據有 0 0,答案為 1,請選手特判以正常通過。 Height ≤ 139 \text{Height}\leq139 Height≤139。 題目描述 對于一個 01 \tt 01 01 串 S S S(下標從 1 1 1 開始)…

【Linux】24.進程信號(1)

文章目錄 1. 信號入門1.1 進程與信號的相關知識1.2 技術應用角度的信號1.3 注意1.4 信號概念1.5 信號處理常見方式概覽 2. 產生信號2.1 通過終端按鍵產生信號2.2 調用系統函數向進程發信號2.3 由軟件條件產生信號2.4 硬件異常產生信號2.5 信號保存 3. 阻塞信號3.1 信號其他相關…

《手札·開源篇》從開源到商業化:中小企業的低成本數字化轉型路徑 ——以Odoo為數據中臺低成本實現售前售中一體化

某機電設備有限公司數字化轉型案例:以Odoo為數據中臺實現售前售中一體化 一、企業背景某機電設備有限公司在機電設備領域歷經多年發展,業務廣泛,涵蓋工業自動化設備、電力設備等產品的銷售與服務。隨著業務版圖不斷拓展,企業面臨…

筆試-業務邏輯4

應用 小明在玩一個數字加減游戲&#xff0c;輸入4個正整數&#xff1a;s、t、a、b&#xff0c;其中s>1&#xff0c;b<105&#xff0c;a!b。只使用加法或者減法&#xff0c;使得st。 每回合&#xff0c;小明用當前的數字&#xff0c;加上或減去一個數字&#xff1b;目前有…

Windows 中的 WSL:開啟你的 Linux 之旅

今天在安裝windows上安裝Docker Desktop的時候&#xff0c;遇到了WSL。下面咱們就學習下。 歡迎來到濤濤聊AI 一、什么是 WSL&#xff1f; WSL&#xff0c;全稱為 Windows Subsystem for Linux&#xff0c;是微軟為 Windows 系統開發的一個兼容層&#xff0c;它允許用戶在 Win…

編程題-電話號碼的字母組合(中等)

題目&#xff1a; 給定一個僅包含數字 2-9 的字符串&#xff0c;返回所有它能表示的字母組合。答案可以按 任意順序 返回。 給出數字到字母的映射如下&#xff08;與電話按鍵相同&#xff09;。注意 1 不對應任何字母。 解法一&#xff08;哈希表動態添加&#xff09;&#x…

python:如何播放 .spx 聲音文件

.spx 是 Speex音頻編解碼器的文件擴展名&#xff0c;它是一種開源的、免費的音頻編解碼器&#xff0c;主要用于語音壓縮和語音通信領域。spx 文件通常用于語音記錄、VoIP應用、語音信箱等場景。 .mp3 是一種廣泛使用的音頻格式&#xff0c;它采用了有損壓縮算法&#xff0c;可…

數據結構課程設計(三)構建決策樹

3 決策樹 3.1 需求規格說明 【問題描述】 ID3算法是一種貪心算法&#xff0c;用來構造決策樹。ID3算法起源于概念學習系統&#xff08;CLS&#xff09;&#xff0c;以信息熵的下降速度為選取測試屬性的標準&#xff0c;即在每個節點選取還尚未被用來劃分的具有最高信息增益的…