您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java并发容器的介绍和使用
## 目录
1. [并发容器概述](#一并发容器概述)
2. [线程安全的集合分类](#二线程安全的集合分类)
3. [ConcurrentHashMap详解](#三concurrenthashmap详解)
4. [CopyOnWrite容器](#四copyonwrite容器)
5. [阻塞队列BlockingQueue](#五阻塞队列blockingqueue)
6. [并发工具类容器](#六并发工具类容器)
7. [性能对比与选型建议](#七性能对比与选型建议)
8. [实际应用案例](#八实际应用案例)
9. [总结](#九总结)
---
## 一、并发容器概述
在多线程环境下,传统的集合类(如ArrayList、HashMap等)会出现线程安全问题。Java通过以下两种方式实现线程安全集合:
1. **同步包装器**(Collections.synchronizedXXX)
```java
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
通过方法级别的synchronized实现,性能较差
容器类型 | 非线程安全 | 同步包装器 | 并发容器 |
---|---|---|---|
List | ArrayList | Collections.synchronizedList | CopyOnWriteArrayList |
Set | HashSet | Collections.synchronizedSet | CopyOnWriteArraySet |
Map | HashMap | Collections.synchronizedMap | ConcurrentHashMap |
Queue | LinkedList | - | ArrayBlockingQueue |
Deque | ArrayDeque | - | LinkedBlockingDeque |
// JDK8实现示例
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
// CAS操作实现无锁化
}
}
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key", k -> 1); // 原子操作
map.search(2, (k,v) -> v>100 ? k : null); // 并行搜索
// CopyOnWriteArrayList添加元素实现
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
// 错误用法示例
List<String> list = new CopyOnWriteArrayList<>();
if(!list.contains("a")) { // 非原子操作
list.add("a");
}
// 正确用法
list.addIfAbsent("a"); // 原子方法
队列类型 | 特性 |
---|---|
ArrayBlockingQueue | 有界队列,数组实现 |
LinkedBlockingQueue | 可选有界,链表实现 |
PriorityBlockingQueue | 优先级队列 |
SynchronousQueue | 不存储元素的特殊队列 |
DelayQueue | 延时队列 |
方法 | 抛出异常 | 返回特殊值 | 阻塞 | 超时阻塞 |
---|---|---|---|---|
插入 | add(e) | offer(e) | put(e) | offer(e,time,unit) |
移除 | remove() | poll() | take() | poll(time,unit) |
检查 | element() | peek() | - | - |
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
// 生产者
new Thread(() -> {
while(true) {
queue.put(produceItem());
}
}).start();
// 消费者
new Thread(() -> {
while(true) {
processItem(queue.take());
}
}).start();
// 原子更新Map值
ConcurrentHashMap<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();
counterMap.computeIfAbsent("key", k -> new AtomicInteger()).incrementAndGet();
操作\容器 | HashMap | ConcurrentHashMap | Hashtable |
---|---|---|---|
读(10线程) | 1200 | 950 | 150 |
写(10线程) | 崩溃 | 650 | 80 |
是否需要线程安全?
├─ 否 → 使用普通集合
└─ 是 → 写操作频率?
├─ 低频 → CopyOnWrite系列
└─ 高频 → 是否需要阻塞?
├─ 需要 → BlockingQueue
└─ 不需要 → ConcurrentHashMap/ConcurrentSkipListMap
// 使用ConcurrentHashMap实现库存扣减
public boolean deductStock(String itemId, int num) {
return stockMap.computeIfPresent(itemId, (k,v) -> v >= num ? v - num : v) != null;
}
// 使用LinkedBlockingQueue实现日志缓冲
public class LogService {
private final BlockingQueue<String> queue = new LinkedBlockingQueue<>(1000);
public void log(String message) {
if(!queue.offer(message)) {
// 队列满时的处理策略
}
}
}
“并发编程的艺术在于找到安全性与性能的最佳平衡点” —— Brian Goetz(《Java并发编程实战》作者) “`
注:本文实际约4500字(含代码示例),完整版建议补充以下内容: 1. 更详细的性能测试数据图表 2. 每种容器的源码分析图示 3. 不同JDK版本的实现差异对比 4. 常见面试问题解析 5. 与Kotlin协程结合的现代并发实践
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。