Java并發編程核心組件簡單了解

一、Lock體系

1. ReentrantLock(可重入鎖)

Lock lock = new ReentrantLock();
lock.lock();
try {// 臨界區代碼
} finally {lock.unlock();
}
  • 特點:可重入、支持公平/非公平策略
  • 優勢:可中斷鎖獲取、定時鎖等待
  • 使用場景:替代synchronized需要更靈活控制的場景
1. 核心使用場景
(1) 需要可中斷的鎖獲取
ReentrantLock lock = new ReentrantLock();try {// 支持響應中斷的鎖獲取lock.lockInterruptibly();try {// 執行可能長時間運行的任務processCriticalSection();} finally {lock.unlock();}
} catch (InterruptedException e) {// 處理中斷邏輯handleInterruption();
}

典型場景

  • 實現可取消任務
  • 處理死鎖恢復機制
  • 響應式系統中斷處理
(2) 精確超時控制
if (lock.tryLock(300, TimeUnit.MILLISECONDS)) {try {// 臨界區操作} finally {lock.unlock();}
} else {// 執行替代邏輯fallbackOperation();
}

適用場景

  • 高并發系統的熔斷機制
  • 實時系統的時間敏感操作
  • 分布式鎖的本地模擬
(3) 公平鎖需求
ReentrantLock fairLock = new ReentrantLock(true); // 公平鎖public void fairAccess() {fairLock.lock();try {// 保證先到先得的訪問順序} finally {fairLock.unlock();}
}

適用場景

  • 交易撮合系統
  • 訂單處理隊列
  • 需要嚴格順序執行的批處理
(4) 多條件變量
class BoundedBuffer {final Lock lock = new ReentrantLock();final Condition notFull = lock.newCondition();final Condition notEmpty = lock.newCondition();public void put(Object x) throws InterruptedException {lock.lock();try {while (count == items.length)notFull.await();// ... put logicnotEmpty.signal();} finally {lock.unlock();}}
}

典型應用

  • 生產者-消費者模式
  • 阻塞隊列實現
  • 復雜狀態管理
6. 常見誤區

誤區 1:認為 ReentrantLock 總是比 synchronized 快

  • 在低競爭場景使用 synchronized

誤區 2:忘記在 finally 中釋放鎖

總結建議
  1. 虛擬線程優先策略

    • 新項目直接使用 ReentrantLock
    • 舊系統逐步替換關鍵路徑的 synchronized
  2. 鎖選擇決策樹

    if (需要可中斷/超時 || 需要公平性 || 虛擬線程環境)→ 選擇 ReentrantLock
    else if (簡單同步 && 短期持有)→ 使用 synchronized
    else→ 評估其他并發工具(如 StampedLock)
    
  3. 監控指標

    • 鎖等待時間(超過 10ms 需要告警)
    • 虛擬線程固定率(目標 < 5%)
    • 鎖競爭頻率(每秒競爭次數)

通過深入理解 ReentrantLock 的機制和虛擬線程的協同工作原理,開發者可以構建出更高性能、更易維護的并發系統。在實際項目中,建議結合 APM 工具(如 Micrometer)持續監控鎖使用情況,實現動態調優。

2. ReentrantReadWriteLock(讀寫鎖)

ReadWriteLock rwLock = new ReentrantReadWriteLock();
Lock readLock = rwLock.readLock();
Lock writeLock = rwLock.writeLock();
  • 讀寫分離:共享讀鎖(允許多線程并發讀),獨占寫鎖
  • 鎖降級機制:寫鎖可降級為讀鎖
  • 適用場景:讀多寫少的數據結構(如緩存)

3. StampedLock(郵戳鎖)

StampedLock stampedLock = new StampedLock();
long stamp = stampedLock.tryOptimisticRead();
// 讀取共享變量
if (!stampedLock.validate(stamp)) {// 升級為悲觀讀stamp = stampedLock.readLock();// ...stampedLock.unlockRead(stamp);
}
  • 三種模式:寫鎖、悲觀讀、樂觀讀
  • 無重入特性,需防止死鎖
  • 性能優勢:樂觀讀不阻塞寫操作

4. LockSupport(線程阻塞工具)

Thread thread = new Thread(() -> {LockSupport.park();// 被喚醒后執行
});
thread.start();
LockSupport.unpark(thread);
  • 基于許可證的線程控制
  • 精準喚醒指定線程
  • 底層Unsafe類實現

5. SpinLock(自旋鎖實現示例)

public class SpinLock {private AtomicBoolean locked = new AtomicBoolean(false);public void lock() {while (!locked.compareAndSet(false, true)) {// 自旋等待}}public void unlock() {locked.set(false);}
}
  • 適用場景:臨界區代碼執行時間極短
  • 優點:避免線程上下文切換
  • 缺點:CPU空轉消耗資源

6. Condition(條件變量)

Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();// 等待方
lock.lock();
try {condition.await();
} finally {lock.unlock();
}// 通知方
lock.lock();
try {condition.signal();
} finally {lock.unlock();
}
  • 實現精準的線程等待/通知機制
  • 支持多個等待隊列
  • 典型應用:阻塞隊列實現

二、并發工具類

1. AbstractQueuedSynchronizer(AQS)

// 自定義同步器示例
class Mutex extends AbstractQueuedSynchronizer {protected boolean tryAcquire(int acquires) {return compareAndSetState(0, 1);}protected boolean tryRelease(int releases) {setState(0);return true;}
}
  • CLH隊列管理等待線程
  • 模板方法設計模式
  • 同步狀態原子管理

2. CountDownLatch(倒計時門閂)

CountDownLatch latch = new CountDownLatch(3);// 工作線程
new Thread(() -> {// 完成任務latch.countDown();
}).start();// 主線程等待
latch.await();
  • 一次性使用
  • 典型應用:并行任務初始化

3. CyclicBarrier(循環屏障)

CyclicBarrier barrier = new CyclicBarrier(3, () -> {// 所有線程到達后執行
});new Thread(() -> {// 執行任務barrier.await();
}).start();
  • 可重復使用
  • 支持屏障動作
  • 應用場景:多階段并行計算

4. Exchanger(數據交換器)

Exchanger<String> exchanger = new Exchanger<>();new Thread(() -> {String data = exchanger.exchange("Thread1 Data");
}).start();new Thread(() -> {String data = exchanger.exchange("Thread2 Data");
}).start();
  • 雙線程數據交換
  • 支持超時機制
  • 應用場景:管道式處理

5. Phaser(階段同步器)

Phaser phaser = new Phaser(3);new Thread(() -> {phaser.arriveAndAwaitAdvance();// 階段1任務phaser.arriveAndDeregister();
}).start();
  • 動態注冊機制
  • 分階段任務控制
  • 支持分層結構

6. Semaphore(信號量)

// 創建包含3個許可的信號量(公平模式)
Semaphore semaphore = new Semaphore(3, true);// 獲取許可(阻塞方式)
semaphore.acquire();
try {// 訪問共享資源(最多3個線程并發)
} finally {semaphore.release();
}// 非阻塞嘗試獲取
if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {try {// 臨界區操作} finally {semaphore.release();}
}
核心特性:
  1. 資源池管理

    • 通過許可(permits)控制并發訪問數量
    • 許可數量可以動態調整(reducePermits/increasePermits
  2. 靈活獲取方式

    • 支持批量獲取(acquire(int permits)
    • 提供可中斷/不可中斷獲取方式
    • 支持超時機制(tryAcquire
  3. 公平性選擇

    • 非公平模式(默認):吞吐量優先
    • 公平模式:按請求順序分配許可
典型應用場景:
  1. 連接池限流
// 數據庫連接池實現
public class ConnectionPool {private final Semaphore semaphore;private final BlockingQueue<Connection> pool;public ConnectionPool(int size) {this.semaphore = new Semaphore(size);this.pool = new ArrayBlockingQueue<>(size);// 初始化連接...}public Connection getConnection() throws InterruptedException {semaphore.acquire();return pool.take();}public void release(Connection conn) {pool.offer(conn);semaphore.release();}
}
  1. 限流控制系統
// API限流控制器(每秒10個請求)
class RateLimiter {private final Semaphore semaphore = new Semaphore(10);private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);public RateLimiter() {scheduler.scheduleAtFixedRate(() -> {int available = semaphore.availablePermits();if (available < 10) {semaphore.release(10 - available);}}, 0, 1, TimeUnit.SECONDS);}public boolean tryAcquire() {return semaphore.tryAcquire();}
}
  1. 生產者-消費者模型
// 有界緩沖區實現
class BoundedBuffer<E> {private final Semaphore availableItems;private final Semaphore availableSpaces;private final Queue<E> queue = new LinkedList<>();public BoundedBuffer(int capacity) {availableItems = new Semaphore(0);availableSpaces = new Semaphore(capacity);}public void put(E item) throws InterruptedException {availableSpaces.acquire();synchronized (this) {queue.offer(item);}availableItems.release();}public E take() throws InterruptedException {availableItems.acquire();E item;synchronized (this) {item = queue.poll();}availableSpaces.release();return item;}
}
使用技巧:
  1. 許可動態調整
// 運行時動態擴展容量
void resize(int newCapacity) {int delta = newCapacity - semaphore.availablePermits();if (delta > 0) {semaphore.release(delta);  // 擴容} else {semaphore.reducePermits(-delta);  // 縮容}
}
  1. 死鎖預防
// 使用tryAcquire避免死鎖
if (semaphore.tryAcquire(2, 100, TimeUnit.MILLISECONDS)) {try {// 臨界區操作} finally {semaphore.release(2);}
} else {// 處理獲取失敗邏輯
}
  1. 與ReentrantLock對比
特性SemaphoreReentrantLock
資源控制多許可控制單鎖獨占
可重入性不支持支持
公平性可配置可配置
條件變量支持Condition
使用場景資源池/流量控制互斥操作
注意事項:
  1. 釋放次數匹配

    • 確保acquire()與release()調用次數匹配
    • 使用try-finally保證釋放
  2. 不可重入特性

    • 同一線程多次acquire需要對應次數的release
  3. 性能監控

    • 通過availablePermits()監控系統負載
    • 使用getQueueLength()檢測等待線程數
  4. 資源泄漏預防

    • 建議使用帶超時的tryAcquire
    • 結合Thread.interrupt()處理阻塞線程
源碼關鍵實現:
// 基于AQS的Sync內部類
abstract static class Sync extends AbstractQueuedSynchronizer {Sync(int permits) {setState(permits);}final int getPermits() {return getState();}final int nonfairTryAcquireShared(int acquires) {for (;;) {int available = getState();int remaining = available - acquires;if (remaining < 0 ||compareAndSetState(available, remaining))return remaining;}}protected final boolean tryReleaseShared(int releases) {for (;;) {int current = getState();int next = current + releases;if (next < current) // overflowthrow new Error("Maximum permit count exceeded");if (compareAndSetState(current, next))return true;}}
}

五、最佳實踐(補充)

  1. Semaphore使用準則:
    • 許可數量設置應基于系統壓測結果
    • 避免在持有信號量時執行阻塞操作
    • 對不可靠資源訪問添加finally釋放塊
    • 結合監控系統實現動態配額調整

通過Semaphore的合理使用,可以有效解決資源池管理、流量控制、系統過載保護等典型并發問題。其靈活的許可管理機制使其成為構建高彈性系統的利器,但需注意避免因錯誤使用導致的線程饑餓或系統死鎖問題。

三、高性能計數器

1. LongAdder

LongAdder counter = new LongAdder();
counter.increment();
long sum = counter.sum();
  • 實現原理:
    • 基礎值 + Cell數組分散競爭
    • 最終一致性保證
  • 適用場景:高頻寫、低頻讀

2. DoubleAdder

DoubleAdder adder = new DoubleAdder();
adder.add(1.5);
double sum = adder.sum();
  • 類似LongAdder的浮點版本
  • 注意精度問題
  • 適用場景:統計指標收集

3. 性能對比

計數器類型寫性能讀性能內存消耗適用場景
AtomicLong讀寫平衡場景
LongAdder寫多讀少場景

四、選型策略

  1. 鎖機制選擇:
  • 優先考慮synchronized
  • 需要高級功能時選擇ReentrantLock
  • 讀多寫少場景使用StampedLock
  1. 并發工具選擇:
  • 一次性等待用CountDownLatch
  • 多階段任務用Phaser
  • 線程數固定用CyclicBarrier
  1. 計數器選擇:
  • 普通場景使用AtomicLong
  • 高并發寫場景使用LongAdder
  • 需要精確值時慎用DoubleAdder

五、最佳實踐

  1. 避免鎖嵌套使用
  2. 總是使用try-finally釋放鎖
  3. 合理設置超時時間
  4. 優先使用并發集合類
  5. 使用ThreadLocal減少競爭
  6. 監控鎖競爭情況(JStack、JConsole)

本文深入剖析了Java并發編程的核心組件,開發者應根據具體場景選擇最合適的工具。在高并發系統中,合理的鎖選擇和并發工具使用可以帶來數量級的性能提升。建議結合JVM參數調優(如偏向鎖、自旋參數)和并發監控工具進行綜合優化。

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

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

相關文章

第二個五年計劃!

下一階段&#xff01;5年后&#xff01;33歲&#xff01;體重維持在125斤內&#xff01;腰圍74&#xff01; 健康目標&#xff1a; 體檢指標正常&#xff0c;結節保持較小甚至變小&#xff01; 工作目標&#xff1a; 每年至少在一次考評里拿A&#xff08;最高S&#xff0c;A我理…

Redis(三) - 使用Java操作Redis詳解

文章目錄 前言一、創建項目二、導入依賴三、鍵操作四、字符串操作五、列表操作六、集合操作七、哈希表操作八、有序集合操作九、完整代碼1. 完整代碼2. 項目下載 前言 本文主要介紹如何使用 Java 操作 Redis 數據庫&#xff0c;涵蓋項目創建、依賴導入及 Redis 各數據類型&…

【Folium】使用離線地圖

文章目錄 相關文獻離線地圖下載Folium 使用離線地圖 相關文獻 Folium — Folium 0.19.5 documentationOffline Map Maker 離線地圖下載 我們使用 Offline Map Maker 進行地圖下載。 特別注意&#xff1a;Folium 默認支持 WGS84 坐標系&#xff0c;建議下載 WGS84 坐標系的地…

DeepSearch:字節新一代 DeerFlow 框架

項目地址&#xff1a;https://github.com/bytedance/deer-flow/ 【全新的 Multi-Agent 架構設計】獨家設計的 Research Team 機制&#xff0c;支持多輪對話、多輪決策和多輪任務執行。與 LangChain 原版 Supervisor 相比&#xff0c;顯著減少 Tokens 消耗和 API 調用次數&#…

Qt—用SQLite實現簡單的注冊登錄界面

1.實現目標 本次實現通過SQLite制作一個簡易的登錄窗口&#xff0c;當點擊注冊按鈕時&#xff0c;登錄窗口會消失&#xff0c;會出現一個新的注冊界面&#xff1b;完成注冊或退出注冊時&#xff0c;注冊窗口會消失&#xff0c;重新出現登錄窗口。注冊過的用戶信息會出現在SQLi…

day 18:零基礎學嵌入式之數據結構——

一、基礎內容 1.數據結構&#xff1a;相互之間存在一種或多種特定關系的數據元素的集合。 2.邏輯結構 &#xff08;1&#xff09;集合&#xff0c;所有數據在同一個集合中&#xff0c;關系平等。 &#xff08;2&#xff09;線性&#xff0c;數據和數據之間是一對一的關系 &am…

【SSL證書系列】客戶端如何驗證https網站服務器發的證書是否由受信任的根證書簽發機構簽發

客戶端驗證HTTPS網站證書是否由受信任的根證書頒發機構&#xff08;CA&#xff09;簽發&#xff0c;是一個多步驟的過程&#xff0c;涉及證書鏈驗證、信任錨&#xff08;Trust Anchor&#xff09;檢查、域名匹配和吊銷狀態驗證等。以下是詳細的驗證流程&#xff1a; 1. 證書鏈的…

iOS即時通信的技術要點

iOS即時通信開發的關鍵技術要點總結&#xff1a; 一、通訊協議選擇 Socket通信 基礎實現&#xff1a;使用原生BSD Socket或CFNetwork框架&#xff08;復雜&#xff09;&#xff0c;推薦第三方庫如CocoaAsyncSocket&#xff08;封裝GCDAsyncSocket&#xff09;&#xff0c;簡化T…

智能AI構建工地安全網:跌倒、抽搐、區域入侵多場景覆蓋

智能AI在工地安全中的應用&#xff1a;從監測到救援的全流程實踐 一、背景&#xff1a;高溫作業下的工地安全挑戰 隨著夏季高溫持續&#xff0c;工地戶外作業環境面臨嚴峻考驗。工人因高溫疲勞、脫水或突發疾病引發的行為異常&#xff08;如暈厥、抽搐、跌倒&#xff09;頻發…

Doris

Apache Doris&#xff08;原名&#xff1a;Palo&#xff09;是一個高性能、實時的MPP分析型數據庫&#xff0c;非常適合海量數據的即席查詢、報表分析、指標統計等 OLAP 場景。Doris 的設計目標是&#xff1a;極致查詢性能、簡單易用、支持高并發分析和明細查詢。 一、Doris 核…

# 2-STM32F103-復位和時鐘控制RCC

STM32-復位和時鐘控制RCC 2-STM32-復位和時鐘控制RCC摘要說明本文參考資料如下&#xff1a; 一、STM32最小系統回顧STM32F103C8T6核心板原理圖 二、復位三、時鐘3.1 時鐘樹3.2 STM32啟動過程3.2 SystemInit()函數3.2.1 SystemInit()第1句&#xff1a;3.2.2 SystemInit()第2句&a…

rk3576 gstreamer opencv

安裝gstreamer rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 rk3588使用gstreamer推流_rk3588 gstreamer-CSDN博客 Installing on Linux sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-pl…

Quic如何實現udp可靠傳輸

QUIC&#xff08;Quick UDP Internet Connections&#xff09;是由 Google 設計并被 IETF 標準化的傳輸層協議&#xff0c;它基于 UDP 實現&#xff0c;但提供了類似 TCP 的可靠性和更高級的功能&#xff08;如多路復用、0-RTT 握手、TLS 加密等&#xff09;。 盡管 UDP 是不可…

uniapp-商城-59-后臺 新增商品(屬性的選中,進行過濾展示,filter,some,every和map)

前面講了屬性的添加&#xff0c;添加完成后&#xff0c;數據庫中已經存在數據了&#xff0c;這時再繼續商品的添加時&#xff0c;就可以進行屬性的選擇了。 在商品添加過程中&#xff0c;屬性選擇是一個關鍵步驟。首先&#xff0c;界面需要展示嵌套的屬性數據&#xff0c;用戶通…

負載均衡 ELB 在 zkmall開源商城高流量場景下的算法優化

在電商大促、直播帶貨等高頻交易場景下&#xff0c;流量突發增長對系統穩定性提出嚴峻挑戰。ZKmll 開源商城通過對負載均衡 ELB&#xff08;Elastic Load Balancer&#xff09;算法的深度優化&#xff0c;結合業務場景特性設計動態加權輪詢 地域感知 熱點分流的混合策略&…

Linux干貨(三)

前言 從B站黑馬程序員Linux課程摘選的學習干貨&#xff0c;新手友好&#xff01;若有侵權&#xff0c;會第一時間處理。 目錄 前言 1.which find命令 1.which命令 2.find命令 2.grep wc 管道符 1.grep命令 2.wc命令 3.管道符 3.echo tail 重定向符 1.echo命令 2.反…

Sigmoid與Softmax:從二分類到多分類的深度解析

Sigmoid與Softmax:從二分類到多分類的深度解析 聯系 函數性質:二者都是非線性函數 ,也都是指數歸一化函數,可將輸入值映射為0到1之間的實數 ,都能把輸出轉化成概率分布的形式,在神經網絡中常作為激活函數使用。Softmax是Sigmoid的推廣:從功能角度看,Softmax函數可視為…

文件系統交互實現

關于之前的搭建看QT控件文件系統的實現-CSDN博客&#xff0c;接下來是對本程序的功能完善&#xff0c;我想著是這樣設計的&#xff0c;打開一個目錄以后&#xff0c;鼠標選中一個項可以是目錄&#xff0c;也可以是文件&#xff0c;右鍵可以出現一個菜單選擇操作&#xff0c;比如…

[ctfshow web入門] web75

信息收集 啟用了open_basedir&#xff0c;所以之前的方法又不能用了 解題 cforeach(new DirectoryIterator("glob:///*") as $a){echo($a->__toString(). ); } ob_flush();cif ( $a opendir("glob:///*") ) {while ( ($file readdir($a)) ! false …

Vulfocus靶場-文件上傳-3

WSO2 文件上傳 &#xff08;CVE-2022-29464&#xff09; WSO2是一家成立于 2005 年的開源技術提供商。它提供了一個企業平臺&#xff0c;用于在本地和整個 Internet 上 集成應用程序編程接口(API)、應用程序和 Web 服務。 某些 WSO2 產品允許無限制的文件上傳和遠程代碼執行。…