Java中LockSupport.park与unpark使用

在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 等高级同步组件很有帮助。使用时注意许可机制和中断处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值