JDK源码那些事儿之LockSupport

本文详细解析JDK中的LockSupport类,它是AQS的基础,用于实现线程的阻塞和唤醒。LockSupport的park和unpark方法管理线程的permit,非叠加性质使得线程调度更灵活。此外,LockSupport与Object的wait/notify机制不同,它不需要同步锁,且能在不同线程间操作。通过LockSupport实现FIFO互斥锁的示例帮助理解其工作原理。
摘要由CSDN通过智能技术生成

前面一篇文章中说明了Object的阻塞唤醒机制,今天我们要讲解另一个类LockSupport,在AQS中你能看见它的身影,所以需要提前了解其实现和使用机制,便于后面深入AQS的学习

前言

JDK版本号:1.8.0_171

在源码阅读之前希望大家先去阅读几遍注释,其中介绍了LockSupport的设计,实现和使用机制,这里进行简单说明下:

  • 每个使用LockSupport的线程都有一个permit(许可),假如permit可用则不进行阻塞。permit不可用时使用unpark可以使得其处于可用状态,注意,这里permit是不能叠加的,也就是说只有一个
  • park和unpark提供了线程阻塞和线程唤醒操作,park支持中断响应,unpark操作可以在park之前调用,这样相当于先让permit处于可用状态, 那么再调用park就不会进行阻塞
  • park操作支持blocker对象参数,线程阻塞时会记录该对象,以允许监视和诊断工具确定线程被阻塞的原因,注释中推荐使用这种方式
  • LockSupport是被设计用来创建高级同步器工具类,对于大多数并发控制程序来说用处不大

上述有些术语可能令人困惑,这里我们通俗点说,首先需要理解permit(许可),这里也就是相当于一个变量标志,有兴趣可查看Hotspot源码

HotSpot Parker用condition和mutex维护了一个_counter变量,park时,变量_counter置为0,unpark时,变量_counter置为1

连续两次调用park操作,变量不会变成2,还是1,也就是说的不能叠加,你可以自己写代码验证,因为维护的是一个变量标识更新,所以park和unpark的调用没有先后顺序限制:

  • 变量_counter为0(默认),如果调用park,则线程会被阻塞,如果调用unpark,则变量会置为1,唤醒被阻塞的线程(注意,阻塞的线程唤醒后会消耗掉又将变量置为0)
  • 变量_counter为1,如果调用park,则线程不会被阻塞,但是变量会被置为0,如果调用unpark,则变量还是1

简单示例代码如下:

    Thread test = new Thread(new Runnable() {
   
        @Override
        public void run() {
   
            System.out.println("start");
            LockSupport.park(this);// _counter为0,阻塞
            System.out.println("end");

        }
    });
    test.start();

    Thread.sleep(3000);
    System.out.println("ready notify");
    // 线程对应的_counter置为1,同时唤醒阻塞的线程,唤醒的线程消耗掉1置为0
    LockSupport.unpark(test);

FIFOMutex

在AbstractQueuedSynchronizer中使用了LockSupport实现线程阻塞和唤醒操作,所以有必要先进行了解,怎么通过LockSupport实现FIFO互斥锁呢?源码注释处已经提供了思路,非队首线程或者不能更新锁标识的都需要被阻塞,还是挺巧妙的,可以好好理解理解

public class FIFOMutex {
   

    public static void main(String[] args) {
   
        FIFOMutex lock = new FIFOMutex();
        new Thread(new Runnable() {
   
            @Override
            public void run() {
   
                System.out.println(Thread.currentThread()+"111");
                lock.lock();
                System.out.println(Thread.currentThread()+"111");
            }
        }).start();
        new Thread(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值