知易通
第二套高阶模板 · 更大气的阅读体验

ReentrantLock可中断特性:别让等待毁了你的程序

发布时间:2025-12-14 00:47:14 阅读:171 次

你有没有遇到过这种情况:家里做饭,一个人占着灶台不撒手,其他人只能干等着,急得团团转?在编程世界里,线程抢资源就像家人抢灶台,要是没人懂得退一步,整个系统就卡住了。这时候,ReentrantLock 的可中断特性,就像是给每个家庭成员发了个对讲机——等太久可以喊停,别傻等。

什么是 ReentrantLock 的可中断特性

默认情况下,线程调用 lock() 方法时,如果锁被别人占着,就会一直堵着不动,像极了不肯让灶的倔强老爸。但如果你改用 lockInterruptibly(),线程就可以响应中断信号。一旦收到“别等了”的通知,它会立刻放弃等待,抛出 InterruptedException,腾出位置,避免死锁或长时间阻塞。

代码怎么写才靠谱

下面这个例子模拟两个线程争抢同一个锁。其中一个等太久,外面有人看不下去,手动中断它:

ReentrantLock lock = new ReentrantLock();

Thread t1 = new Thread(() -> {
    try {
        System.out.println("t1 尝试获取锁");
        lock.lockInterruptibly();
        try {
            System.out.println("t1 成功拿到锁,开始干活");
            Thread.sleep(5000); // 模拟干活耗时
        } finally {
            lock.unlock();
            System.out.println("t1 释放锁");
        }
    } catch (InterruptedException e) {
        System.out.println("t1 被中断,不再等待");
    }
});

Thread t2 = new Thread(() -> {
    lock.lock();
    try {
        System.out.println("t2 拿到锁,正在占用");
        Thread.sleep(6000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    } finally {
        lock.unlock();
    }
});

t2.start();
Thread.sleep(1000);
t1.start();
Thread.sleep(2000);
t1.interrupt(); // 手动中断 t1

运行结果中你会看到,t1 在等待过程中被中断,没有继续苦熬,而是干净利落地退出。这在实际开发中特别有用,比如用户点击取消操作,后台线程就能及时收手,不浪费资源。

什么时候该用它

当你写的程序需要响应外部指令、支持取消操作,或者担心线程卡死影响整体性能时,lockInterruptibly() 就是你的首选。比如上传文件中途想取消,定时任务超时要退出,都可以靠它实现优雅终止。

别再让线程傻等了,就像家里不该让一个人霸着厨房一整天。用好 ReentrantLock 的可中断特性,让每个“家庭成员”都能进退有度,程序自然更灵活、更健壮。