# 51. 锁中断机制分析
# 标准答案
✅ synchronized和ReentrantLock中断机制的区别:
实现原理差异:
- synchronized基于JVM实现
- ReentrantLock基于AQS实现
- 不同的等待队列机制
- 不同的线程状态管理
中断处理机制:
- synchronized不响应中断
- ReentrantLock支持中断
- 可以避免死锁
- 支持超时获取
使用场景:
- 需要中断时用ReentrantLock
- 简单同步用synchronized
- 超时场景用ReentrantLock
- 高级特性用ReentrantLock
# 答案解析
# 1️⃣ ReentrantLock中断示例
public class LockInterruptExample {
private final ReentrantLock lock = new ReentrantLock();
public void lockInterruptibly() {
try {
// 支持中断的加锁
lock.lockInterruptibly();
try {
// 执行业务逻辑
processData();
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
// 处理中断
handleInterruption();
}
}
public boolean tryLockWithTimeout() {
try {
// 支持超时的加锁
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try {
// 执行业务逻辑
return processData();
} finally {
lock.unlock();
}
}
return false;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
}
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
# 2️⃣ 死锁避免实现
public class DeadlockAvoidance {
private final ReentrantLock lock1 = new ReentrantLock();
private final ReentrantLock lock2 = new ReentrantLock();
public void operation() {
while (true) {
try {
// 尝试获取第一个锁
if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) {
try {
// 尝试获取第二个锁
if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) {
try {
// 获取到所有锁,执行操作
processData();
return;
} finally {
lock2.unlock();
}
}
} finally {
lock1.unlock();
}
}
// 避免活锁
Thread.sleep(RandomUtils.nextInt(1, 10));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Operation interrupted", e);
}
}
}
private void processData() {
// 业务处理逻辑
}
}
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:认为synchronized完全不能处理中断
- ❌ 误区2:过度使用ReentrantLock
# 典型场景与解决方案
# ✅ 资源获取超时处理
public class ResourceManager {
private final ReentrantLock resourceLock = new ReentrantLock();
private final Condition resourceAvailable = resourceLock.newCondition();
public Resource acquireResource(long timeout, TimeUnit unit)
throws InterruptedException {
// 尝试获取锁
if (!resourceLock.tryLock(timeout, unit)) {
throw new TimeoutException("Failed to acquire resource lock");
}
try {
long remainingNanos = unit.toNanos(timeout);
while (resourceNotAvailable()) {
if (remainingNanos <= 0) {
throw new TimeoutException("Resource not available");
}
remainingNanos = resourceAvailable.awaitNanos(remainingNanos);
}
return allocateResource();
} finally {
resourceLock.unlock();
}
}
}
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
# 企业实战经验
# Situation(业务背景)
系统需要处理复杂的资源竞争场景。
# Task(核心任务)
实现可靠的资源获取机制。
# Action(解决方案)
- 使用ReentrantLock
- 实现超时机制
- 处理中断异常
- 避免死锁风险
# Result(结果)
- 系统可靠性提升
- 死锁问题消除
- 响应更及时
# 深入追问
🔹 如何选择synchronized和ReentrantLock?
- 功能需求分析
- 性能要求评估
- 代码复杂度考虑
🔹 如何正确处理中断异常?
- 传递中断标志
- 合理释放资源
- 记录异常信息
# 相关面试题
- ReentrantLock的实现原理?
- 如何实现公平锁?
- Condition的使用场景?