一、可中断锁
1. 核心方法:lockinterruptibly()
- 作用:允许线程在等待锁的过程中响应中断请求。
- 适用场景:需要支持任务取消或中断的同步操作(如用户手动取消长时间等待的任务)。
2. 代码示例
reentrantlock lock = new reentrantlock();
thread thread = new thread(() -> {
try {
lock.lockinterruptibly(); // 可中断获取锁
try {
system.out.println("线程获取锁并执行任务");
thread.sleep(5000); // 模拟耗时操作
} finally {
lock.unlock();
}
} catch (interruptedexception e) {
system.out.println("线程被中断,放弃获取锁");
}
});
lock.lock(); // 主线程先获取锁
try {
thread.start();
thread.sleep(1000); // 确保子线程开始等待锁
thread.interrupt(); // 中断子线程
} finally {
lock.unlock();
}
3. 行为分析
- 未中断时:线程正常获取锁并执行任务。
- 中断时:抛出
interruptedexception,线程退出等待队列。
二、锁超时
1. 核心方法:trylock()
无参方法:
boolean trylock()
立即尝试获取锁,成功返回true,失败返回false。带超时方法:
boolean trylock(long timeout, timeunit unit)
在指定时间内尝试获取锁,超时后放弃。
2. 代码示例:避免死锁
reentrantlock locka = new reentrantlock();
reentrantlock lockb = new reentrantlock();
thread thread1 = new thread(() -> {
try {
if (locka.trylock(1, timeunit.seconds)) { // 尝试获取locka
try {
if (lockb.trylock(1, timeunit.seconds)) { // 尝试获取lockb
system.out.println("thread1完成任务");
}
} finally {
if (lockb.isheldbycurrentthread()) lockb.unlock();
}
}
} catch (interruptedexception e) {
e.printstacktrace();
} finally {
if (locka.isheldbycurrentthread()) locka.unlock();
}
});
thread thread2 = new thread(() -> { /* 类似逻辑,先尝试lockb再locka */ });
thread1.start();
thread2.start();
3. 应用场景
- 死锁预防:通过超时放弃锁请求,打破循环等待。
- 响应性优化:避免线程长时间阻塞影响系统响应速度。
三、条件变量
1. 核心机制
- 创建条件变量:
condition condition = lock.newcondition(); - 等待条件:
condition.await(); - 唤醒线程:
condition.signal()或condition.signalall()
2. 代码示例:生产者-消费者模型
reentrantlock lock = new reentrantlock();
condition notempty = lock.newcondition(); // 非空条件
condition notfull = lock.newcondition(); // 非满条件
queue<integer> queue = new linkedlist<>();
int maxsize = 10;
// 生产者
new thread(() -> {
lock.lock();
try {
while (queue.size() == maxsize) {
notfull.await(); // 等待队列非满
}
queue.add(1);
notempty.signal(); // 通知消费者
} catch (interruptedexception e) {
e.printstacktrace();
} finally {
lock.unlock();
}
}).start();
// 消费者
new thread(() -> {
lock.lock();
try {
while (queue.isempty()) {
notempty.await(); // 等待队列非空
}
queue.poll();
notfull.signal(); // 通知生产者
} catch (interruptedexception e) {
e.printstacktrace();
} finally {
lock.unlock();
}
}).start();
3. 优势对比wait()/notify()
| 特性 | condition | wait()/notify() |
|---|---|---|
| 多条件支持 | ✅ 可创建多个条件变量 | ❌ 每个对象仅一个等待队列 |
| 精准唤醒 | ✅ signal() 唤醒指定条件队列的线程 | ❌ notify() 随机唤醒 |
四、关键注意事项
1. 锁释放
- 必须手动释放:lock.unlock() 需放在 finally 块中确保执行。
- 重入次数匹配:加锁和解锁次数必须一致,否则导致锁无法释放。
2. 中断处理
- 响应中断:lockinterruptibly() 和 await() 需捕获 interruptedexception。
- 恢复中断状态:调用 thread.currentthread().interrupt() 保留中断标志。
到此这篇关于java并发编程之reentrantlock的实现示例的文章就介绍到这了,更多相关java reentrantlock内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论