当前位置: 代码网 > it编程>编程语言>Java > Java并发编程之ReentrantLock的实现示例

Java并发编程之ReentrantLock的实现示例

2026年02月13日 Java 我要评论
一、可中断锁1. 核心方法:lockinterruptibly()作用:允许线程在等待锁的过程中响应中断请求。适用场景:需要支持任务取消或中断的同步操作(如用户手动取消长时间等待的任务)。2. 代码示

一、可中断锁

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()

特性conditionwait()/notify()
多条件支持✅ 可创建多个条件变量❌ 每个对象仅一个等待队列
精准唤醒✅ signal() 唤醒指定条件队列的线程❌ notify() 随机唤醒

四、关键注意事项

1. 锁释放

  • 必须手动释放:lock.unlock() 需放在 finally 块中确保执行。
  • 重入次数匹配:加锁和解锁次数必须一致,否则导致锁无法释放。

2. 中断处理

  • 响应中断:lockinterruptibly() 和 await() 需捕获 interruptedexception。
  • 恢复中断状态:调用 thread.currentthread().interrupt() 保留中断标志。

到此这篇关于java并发编程之reentrantlock的实现示例的文章就介绍到这了,更多相关java reentrantlock内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com