在Java中,LockSupport 它是一种非常基本和重要的线程阻塞工具,位于 java.util.concurrent.locks 包下。它提供的 park() 和 unpark(thread) 与传统相比,该方法用于控制线程的阻塞和唤醒 wait/notify 或 sleep,它更灵活,更底层,不会抛出 InterruptedException(除非中断使用配合响应)。
基本功能说明 park():在发生以下情况之一之前,使当前线程进入阻塞状态:
- 调用其他线程
unpark(thisThread) - 中断当前线程(是否中断响应取决于具体方法)
- 虚假唤醒(很少见,但要注意)
unpark(Thread thread):唤醒指定的线程,如果线程处于阻塞状态,则恢复运行;如果线程没有阻塞,下次调用 park 不会被阻塞(许可证已经存在)。
关键点是:unpark 可以先于 park 调用,这和 wait/notify 必须成对并按不同的顺序执行,以避免因通知丢失而导致的死锁问题。
示例的基本使用
以下是一个简单的线程合作示例:
Thread worker = new Thread(() -> {
System.out.println("工作线程开始执行任务...");
// 阻塞,等待被唤醒
LockSupport.park();
System.out.println("工作线程被唤醒,继续执行!");
});
worker.start();
// 主线程休眠1秒,模拟一些操作
try { Thread.sleep(1000); } catch (InterruptedException e) {}
// 唤醒工作线程
LockSupport.unpark(worker);
// 输出:
// 工作线程开始执行任务...
// 工作线程被唤醒,继续执行!
即使在这个例子中 unpark 在 park 以前的调用,也不会有问题。由于 unpark 给线程一个“许可”,park 先检查是否有许可证,有的直接返回,不堵塞。
与 wait/notify 的主要区别
- 对象锁不需要获取:park/unpark 不依赖 synchronized,使用更自由。
- 许可机制:unpark 发放许可,park 允许先发后收消费许可证。
- 精确唤醒:unpark 直接指定线程,而 notify 随机唤醒一个 wait 线程。
- 更轻量级:基于 UNSAFE 实现,是 AQS 等同步器的基础。
处理中断的 park 方法LockSupport 提供两个版本 park:
wait/notify0:不响应中断,即使线程中断,也可能继续堵塞。wait/notify1 或wait/notify2:可与中断检测相结合。
在实际开发中,通常这样处理中断:
if (Thread.interrupted()) {
// 清除中断状态,提前返回或抛出
}
LockSupport.park();
或者通过判断中断状态来决定是否继续 park。
blocker 的作用
推荐使用 wait/notify3.输入阻塞原因对象(例如) this),该信息将被记录在线程中 wait/notify4 可通过字段 wait/notify5 有助于调试和分析线程状态(如使用) jstack 查看时可以知道卡在哪里)。
基本上就是这些。LockSupport 的 park 和 unpark 是 Java 并承包基石,了解其行为并掌握 AQS、ReentrantLock、Condition 等高级同步组件很有帮助。使用时注意许可机制和中断处理。

4223

被折叠的 条评论
为什么被折叠?



