park unpark使用及其原理

1、基本使用

他们都是 LockSupport 工具类提供的方法,需要先 park 然后再 unpark

// 暂停当前线程
LockSupport.park(); 
// 恢复某个线程的运行
LockSupport.unpark(暂停线程对象)
@SneakyThrows
public static void main(String[] args) {
    Thread t1 = new Thread(() -> {
        log.info("start...");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("park...");
        LockSupport.park();
        log.info("resume...");
    }, "t1");
    t1.start();
    TimeUnit.SECONDS.sleep(2);
    log.info("unpark...");
    LockSupport.unpark(t1);
}

image-20220209133700450

如果先 unparkpark,那么 park 将会失效

@SneakyThrows
public static void main(String[] args) {
    Thread t1 = new Thread(() -> {
        log.info("start...");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("park...");
        LockSupport.park();
        log.info("resume...");
    }, "t1");
    t1.start();
    TimeUnit.SECONDS.sleep(1);
    log.info("unpark...");
    LockSupport.unpark(t1);
}

image-20220209133748790

2、对比wait & notify

  • waitnotifynotifyAll 必须配合 Object Monitor (锁)一起使用,而 parkunpark 不必
  • park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么【精确】
  • park & unpark 可以先 unpark,而 wait & notify 不能先 notify

3、原理

每个线程都有自己的一个 Parker 对象,由三部分组成 _counter_condition_mutex(互斥锁),由底层 c 实现,JAVA 层面不可见,好多 JUC 底层实现都用到了它,打个比喻

  • 线程就像一个旅人,Parker 就像他随身携带的背包,条件变量 _condition 就好比背包中的帐篷。_counter 就好比背包中的备用干粮(0 为耗尽,1 为充足,初始为0),调用park 就是旅人饿了,如果备用干粮耗尽,那么钻进帐篷歇息,否则继续前进,调用 unpark,就好比令干粮充足,因为背包空间有限,多次调用 unpark 仅会补充一份备用干粮,如果这时线程因为饿了还在帐篷,就唤醒让他吃东西继续前进,如果这时线程还在运行,那么下次他调用 park 时,仅是消耗掉备用干粮,不需停留继续前进
  • 也就是说,_counter 一开始等于 0 ,当调用 park ,会先获得 _mutex 互斥锁,然后阻塞,直到调用 unpark 补充干粮,然后唤醒继续上路,如果一开始还没饿,也就是还没有调用 park,先调用 unpark 补充干粮,那么 _counter 就先变为 1,等到再执行 park 的时候,发现还有干粮,就不阻塞了,直接运行
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值