【多线程】LockSupport的线程等待唤醒机制

前言:

传统的线程等待唤醒机制有两种方式分别是synchronized(wait和notify)和JUC包中的显示锁Lock(condition的await()方法和signal()方法),但是这两个方式有两个缺点,分别是都不能脱离synchronized,和lock、unlock,如果脱离就会报错,还有就是wait和notify,await和signal的执行顺序要固定,必须先wait然后在notify,否则会导致程序无法结束。

所以出现第三种方式,那就是LockSupport(park和unpark),LockSupport类可以阻塞当前线程以及唤醒指定被阻塞的线程。接下来详细介绍。

1、LockSupport介绍

  • LockSupport是用来创建锁和其他同步类的基本线程阻塞原语
  • LockSupport类使用了一种名为Permit(许可)的概念来做到阻塞和唤醒线程的功能,每个线程都有一个许可(Permit),Permit只有两个值1和0,默认是0
  • 把许可看成是一种(0,1)信号量(Semaphore),但是与Semaphore不同的是,许可的累加上限是1.
  • 两个方法
    park()/park(Object blocker):阻塞当前线程/阻塞传入的具体线程
    unpark(Thread thread):唤醒处于阻塞状态的指定线程
  • 调用一次unpark就加1 ,最大就是1
  • 调用一次park会消费permit,也就是将1变成0,同时park立即返回。如果再次用park就会阻塞,这时调用unpark会把permit置为1
  • 每个线程都有一个相关的permit,permit最多只有一个,重复调用unpark也不会累计凭证

2、代码验证

  public static void main(String[] args) {
        Thread a = new Thread(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "\t" + "-----come in " + System.currentTimeMillis());
            LockSupport.park();  // 被阻塞....等待通知,他需要通过许可证
            System.out.println(Thread.currentThread().getName() + "\t" + "-----被 唤 醒 " + System.currentTimeMillis());
        }, "a");
        a.start();

        Thread b = new Thread(() -> {
            LockSupport.unpark(a);
            System.out.println(Thread.currentThread().getName() + "\t" + "-----通知了");
        }, "b");
        b.start();
    }

执行结果:
在这里插入图片描述
首先 park和unpark 不需要锁块, 其次根据上面的结果我们看出 先unpark(唤醒)后park(等待)也同样支持

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值