java LockSupport类详解

1、LockSupport类简介

LockSupport类,是JUC包中的一个工具类,是用来创建锁和其他同步类的基本线程阻塞原语。

LockSupport类的核心方法有两个:park()和unpark(),其中park()方法用来阻塞当前调用线程,unpark()方法用于唤醒指定线程。这其实和Object类的wait()和singal()方法有些类似,但是LockSupport的这两种方法从语义上将比Object类的方法更清晰,而且可以针对指定线程进行阻塞和唤醒。

LockSupport类使用了一种名为Permit(许可证)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量(Semaphore),但与Semaphore不同的是,许可的累加上限是1。初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。

2、park()方法

如果调用park方法的线程已经拿到了与LockSupport关联的许可证,则调用LockSupport.park()时会马上返回,否则调用线程会被禁止参与线程的调度,也就是会被阻塞挂起。

public static void main(String[] args) {
    System.out.println("begin park");
    LockSupport.park();
    System.out.println("end park");
}
  • 上面代码最终只会输出begin park,然后当前线程被挂起,这是因为在默认情况下调用线程是不持有许可证的。

在其他线程调用unpark(Thread thread)方法并且将当前线程作为参数时,调用park方法而被阻塞的线程会返回。另外,如果其他线程调用了阻塞线程的interrupt()方法,设置了中断标志或者线程被虚假唤醒,则阻塞线程也会返回。所以在调用park方法时最好也是用循环条件判断方式。

需要注意的是,因调用方法而被阻塞的线程被其他线程中断而返回时并不会抛出InterruptedException异常。

3、unpark(Thread thread)方法

当一个线程调用unpark时,如果参数thread线程没有持有thread与LockSupport类关联的许可证,则让thread线程持有。如果thread之前因调用park()而被挂起,则调用unpark后,该线程被唤醒。如果thread之前没有调用park,则调用unpark方法后,再调用park方法,其会立刻返回。

public class UnparkTest {
    public static void main(String[] args) {
        System.out.println("begin park");

        // 使用当前线程获取许可证
        LockSupport.unpark(Thread.currentThread());

        // 再次调用park方法
        LockSupport.park();

        System.out.println("end park");
    }
}

4、使用示例

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("child thread begin park");
            // 调用park方法,挂起自己
            LockSupport.park();
            System.out.println("child thread unpark");
        }
    });
    // 启动子线程
    thread.start();
    // 主线程休眠1s
    Thread.sleep(1000);
    System.out.println("main thread begin unpark");
    // 调用unpark方法让thread线程持有许可证,然后park方法返回
    LockSupport.unpark(thread);
}

执行程序:

child thread begin park
main thread begin unpark
child thread unpark

Process finished with exit code 0
  •  上面代码首先创建了一个子线程thread,子线程启动后调用park方法,由于再默认情况下子线程没有持有许可证,因而它会把自己挂起
  • 主线程休眠1秒是为了让主线程调用unpark方法前让子线程输出child thread begin park并阻塞
  • 主线程然后执行unpark方法,参数为子线程,这样做的目的是让子线程持有许可证,然后子线程调用的park方法就返回了
  • park方法返回时不会告诉你因何种原因返回,所以调用者需要根据之前调用park方法的原因,再次检查条件是否满足,如果不满足则还需要再次调用park方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值