park & unpark

目录

一、基本使用

二、特点(与 wait/notify 对比)

三、park & unpark 的原理


一、基本使用

1. park 和 unpark 是 LockSupport 中的方法

2. LockSupport.park();// 暂停线程,线程进入 WAIT 状态

3. LockSupport.unpark(被暂停的线程);// 恢复被暂停线程的运行

二、特点(与 wait/notify 对比)

1. park/unpark 既可以在线程被 park 之后调用,也可以在 park 之前调用,都可以恢复线程的运行;wait/notify 只能先 wait 再 notify

2. wait/notify 需要配合 Object Monitor 来使用,park/unpark 不需要

3. park/unpark 是以线程为单位,而 notify 只能随机唤醒 Monitor 上的一个等待线程,notifyAll 是唤醒所有等待线程,没有 park/unpark 精确

三、park & unpark 的原理

park 和 unpark 底层是 C 实现的,Java 层面看不到

1. 介绍:每个线程都会关联一个 Parker 对象,由三部分组成 _counter、_cond 和 _mutex,_counter 为 1 表示不需要阻塞可以继续运行,_counter 为 0 表示需要进入 _cond 阻塞,要等到 unpark 将 _counter 设置为 1 之后才能运行

  • park():检查 counter 的状态,如果是 0,当前线程就进入 condition 阻塞,如果是 1,说明不需要阻塞,可以继续运行,同时将 counter 设置为 1
  • unpark():将 counter 状态设置为 1,判断线程是否在 cond 中阻塞,如果在则唤醒它继续执行,唤醒之后将 counter 重新设置为 0;如果线程处于运行状态时调用 unpark,当下次调用 park 进行阻塞时就不会被阻塞,而是继续运行(因为 park 先检查发现 counter 是 1,所以不会进入 cond)

2. park

  •  当前线程调用 Unsafe.park() 方法
  • 检查 counter 为 0(没调用 unpark,初始为 0),获取 mutex 互斥锁
  • 进入 cond 条件变量阻塞
  • 设置 counter 为 0

3. 先 park 再 unpark 的 unpark

  • 调用 Unsafe.unpark(Thread_0) 方法,设置 counter 为 1
  • 唤醒 cond 条件变量中的 Thread_0
  • Thread_0 恢复运行
  • 设置 counter 为 0

4. 先 unpark 再 park 的 unpark

  • 调用 Unsafe.unpark(Thread_0) 方法,设置 counter 为 1
  • 调用 Unsafe.park()
  • 检查 counter 发现是 1,无需阻塞,Thread_0 继续运行
  • 设置 counter 为 0

如果之后调用 park,还是会被阻塞,因为上次调用 park 之后 counter 已经设置成了 0,需要再次的 unpark 将 counter 设置为 1 唤醒线程才能继续运行

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值