首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 並發進階:並發集合、原子變量與 ThreadLocalRandom 實戰

     編輯:Java 綜合教學

Java 並發進階:並發集合、原子變量與 ThreadLocalRandom 實戰

在多核處理器普及的今天,java.util.concurrent 包提供的高級並發組件是構建高性能多線程應用的基石。本文系統梳理並發集合、原子變量、並發隨機數三大核心組件的用法與原理。

一、並發集合:線程安全的數據結構

java.util.concurrent 根據接口將集合分為三大類,均建立了 happens-before 關係,避免內存一致性錯誤。

1. BlockingQueue - 生產者/消費者首選

  • 定義 FIFO 阻塞隊列,滿隊列入隊阻塞/超時,空隊列出隊阻塞/超時。
  • 常用實現:ArrayBlockingQueue(有界)、LinkedBlockingQueue(可選有界)、SynchronousQueue(直接傳遞)。

2. ConcurrentMap - 原子化 Map 操作

  • 繼承 Map,新增 putIfAbsent、remove(key, value)、replace(key, old, new) 等原子方法。
  • 標準實現 ConcurrentHashMap:分段鎖(JDK 7)或 CAS+synchronized(JDK 8+),高併發讀寫性能遠優於 Collections.synchronizedMap。

3. ConcurrentNavigableMap - 支持有序操作

  • 繼承 ConcurrentMap,提供 ceilingEntry、floorKey 等近似匹配。
  • 標準實現 ConcurrentSkipListMap:基於跳表,並發版 TreeMap。

二、原子變量:無鎖線程安全計數

java.util.concurrent.atomic 包下的類(AtomicInteger、AtomicLong、AtomicReference 等)利用 CPU CAS 指令實現無鎖原子操作,讀寫語義等同 volatile。

核心方法

  • get() / set():volatile 讀寫
  • incrementAndGet() / decrementAndGet():原子增減
  • compareAndSet(expect, update):CAS 核心,成功返回 true
  • getAndAdd(delta):原子加法並返回舊值

計數器實戰範例

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicCounter {
    private final AtomicInteger count = new AtomicInteger(0);
    
    public void increment() { count.incrementAndGet(); }
    public void decrement() { count.decrementAndGet(); }
    public int value() { return count.get(); }
}

三、並發隨機數:ThreadLocalRandom

JDK 7 引入,解決 Math.random() 多線程爭用種子導致的性能瓶頸。每個線程持有獨立種子,無競爭、無共享狀態。

用法


// 獲取當前線程專屬實例
ThreadLocalRandom random = ThreadLocalRandom.current();

// 生成 [4, 77) 之間的隨機整數
int r = random.nextInt(4, 77);

// 長整型、雙精度同理
long l = random.nextLong(100, 1000);
double d = random.nextDouble(0.0, 1.0);

性能對比

指標Math.random()ThreadLocalRandom
線程爭用高(共享 AtomicLong 種子)無(ThreadLocal 隔離)
吞吐量隨線程數線性下降近乎水平擴展

最佳實踐建議

  • 高併發計數、ID 生成優先用 AtomicLong/AtomicInteger,避免鎖開銷。
  • 共享 Map 場景直接用 ConcurrentHashMap,拒絕手寫同步包裝。
  • 並發隨機數場景(如負載均衡權重、延遲抖動)強制使用 ThreadLocalRandom。
  • 避免在循環中頻繁創建 Random 實例,改用 ThreadLocalRandom.current()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved