# 42. 减少锁竞争的策略分析
# 标准答案
✅ 高并发环境下减少锁竞争的策略:
锁分段:
- 将一个大锁拆分为多个小锁
- 降低锁粒度,减少竞争范围
- 如ConcurrentHashMap的分段锁设计
锁消除:
- 使用ThreadLocal避免共享
- 采用无锁数据结构(CAS)
- 使用局部变量避免共享
锁粗化:
- 合并频繁加锁操作
- 减少锁的请求次数
- 避免反复加锁解锁
读写分离:
- 使用ReadWriteLock
- 读多写少场景性能提升
- 允许并发读操作
# 答案解析
# 1️⃣ 锁分段实现
public class SegmentLockMap<K, V> {
private static final int SEGMENTS = 16;
private final Object[] locks;
private final Map<K, V>[] segments;
public SegmentLockMap() {
locks = new Object[SEGMENTS];
segments = new Map[SEGMENTS];
for (int i = 0; i < SEGMENTS; i++) {
locks[i] = new Object();
segments[i] = new HashMap<>();
}
}
private int getSegment(K key) {
return Math.abs(key.hashCode() % SEGMENTS);
}
public V put(K key, V value) {
int segment = getSegment(key);
synchronized (locks[segment]) {
return segments[segment].put(key, value);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2️⃣ 无锁设计
public class LockFreeCounter {
private AtomicLong value = new AtomicLong(0);
public long increment() {
long current;
long next;
do {
current = value.get();
next = current + 1;
} while (!value.compareAndSet(current, next));
return next;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 常见误区
- ❌ 误区1:过度使用锁分段导致内存占用增加
- ❌ 误区2:盲目使用无锁操作导致性能下降
# 典型场景与解决方案
# ✅ 高并发计数器
public class HighConcurrencyCounter {
// 分片计数器
private final LongAdder counter = new LongAdder();
// 本地计数器
private final ThreadLocal<Long> localCounter = ThreadLocal.withInitial(() -> 0L);
public void increment() {
// 先在本地计数
localCounter.set(localCounter.get() + 1);
// 定期同步到全局计数器
if (localCounter.get() % 100 == 0) {
counter.add(localCounter.get());
localCounter.set(0L);
}
}
public long getCount() {
// 合并所有线程的本地计数
long total = counter.sum();
for (Thread thread : Thread.getAllStackTraces().keySet()) {
ThreadLocal<Long> local = localCounter;
if (local != null) {
total += local.get();
}
}
return total;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 企业实战经验
# Situation(业务背景)
电商订单系统在秒杀场景下,库存锁竞争严重。
# Task(核心任务)
优化库存锁设计,提高并发性能。
# Action(解决方案)
- 实现分段库存锁
- 使用本地缓存减少锁访问
- 采用乐观锁机制
- 引入预扣减机制
# Result(结果)
- 系统TPS提升300%
- 锁等待时间减少80%
- 秒杀成功率提升50%
# 深入追问
🔹 如何选择合适的锁分段数量?
- 考虑并发访问量
- 评估内存占用
- 进行性能测试
🔹 在什么情况下不适合使用锁分段?
- 数据强一致性要求
- 频繁的跨段操作
- 内存资源受限
# 相关面试题
- 如何实现高效的分段锁?
- CAS操作的优缺点是什么?
- 如何在保证线程安全的同时提高性能?