# 47. synchronized性能优化分析
# 标准答案
✅ synchronized性能优化策略:
JVM层优化:
- 锁消除(Lock Elimination)
- 锁粗化(Lock Coarsening)
- 偏向锁(Biased Locking)
- 轻量级锁(Lightweight Locking)
代码层优化:
- 缩小同步范围
- 减少锁粒度
- 避免锁嵌套
- 使用ThreadLocal
最佳实践:
- 选择合适的锁范围
- 避免锁竞争热点
- 合理使用锁分离
- 优化锁持有时间
# 答案解析
# 1️⃣ 锁粒度优化
public class OrderService {
// 优化前:对整个方法加锁
public synchronized void processOrder(Order order) {
validateOrder(order);
updateInventory(order);
saveOrder(order);
}
// 优化后:细化锁粒度
public void processOrderOptimized(Order order) {
// 无状态验证,不需要加锁
validateOrder(order);
// 库存更新需要加锁
synchronized(this.getInventoryLock(order.getProductId())) {
updateInventory(order);
}
// 订单保存使用独立锁
synchronized(this.getOrderLock(order.getId())) {
saveOrder(order);
}
}
private Object getInventoryLock(Long productId) {
return inventoryLocks.computeIfAbsent(productId, k -> new Object());
}
private Object getOrderLock(Long orderId) {
return orderLocks.computeIfAbsent(orderId, k -> new Object());
}
}
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
29
30
31
32
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
29
30
31
32
# 2️⃣ 锁分离实现
public class OptimizedCache {
private final Map<String, Object> cache = new ConcurrentHashMap<>();
private final ReadWriteLock[] locks;
private final int lockCount;
public OptimizedCache(int lockCount) {
this.lockCount = lockCount;
this.locks = new ReadWriteLock[lockCount];
for (int i = 0; i < lockCount; i++) {
locks[i] = new ReentrantReadWriteLock();
}
}
public Object get(String key) {
ReadWriteLock lock = getLock(key);
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Object value) {
ReadWriteLock lock = getLock(key);
lock.writeLock().lock();
try {
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
private ReadWriteLock getLock(String key) {
return locks[Math.abs(key.hashCode() % lockCount)];
}
}
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
29
30
31
32
33
34
35
36
37
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
29
30
31
32
33
34
35
36
37
# 常见误区
- ❌ 误区1:过度细化锁粒度导致性能下降
- ❌ 误区2:盲目使用volatile替代synchronized
# 典型场景与解决方案
# ✅ 库存系统优化
public class InventoryManager {
private final int BUCKET_COUNT = 32;
private final Object[] locks = new Object[BUCKET_COUNT];
private final Map<Long, Integer> inventory = new ConcurrentHashMap<>();
public InventoryManager() {
for (int i = 0; i < BUCKET_COUNT; i++) {
locks[i] = new Object();
}
}
public boolean deductStock(long productId, int quantity) {
Object lock = getLock(productId);
synchronized(lock) {
Integer current = inventory.get(productId);
if (current != null && current >= quantity) {
inventory.put(productId, current - quantity);
return true;
}
return false;
}
}
private Object getLock(long productId) {
return locks[(int)(productId % BUCKET_COUNT)];
}
}
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
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
# 企业实战经验
# Situation(业务背景)
订单系统在高并发下锁竞争严重。
# Task(核心任务)
优化synchronized使用,提高系统性能。
# Action(解决方案)
- 实现锁分段
- 优化锁粒度
- 使用读写分离
- 引入ThreadLocal
# Result(结果)
- 系统吞吐量提升150%
- 锁竞争减少80%
- 响应时间降低60%
# 深入追问
🔹 如何判断锁优化的效果?
- 使用JVM工具分析
- 压测比较性能
- 监控锁竞争情况
🔹 锁粗化和锁消除的区别?
- 锁粗化合并相邻同步块
- 锁消除去除不必要的锁
- 不同的优化目标
# 相关面试题
- synchronized锁升级过程?
- 如何避免死锁问题?
- synchronized和ReentrantLock如何选择?