Semaphore底层原理

Semaphore作为多线程同步工具,其核心方法acquire和release分别用于获取和释放许可。它基于AQS(AbstractQueuedSynchronizer)框架,支持公平和非公平模式。在acquire时,线程会尝试获取资源,若state非零则唤醒后续线程;在release时,state值会增加,可能唤醒等待的线程。整个过程涉及AQS的CLH链表队列,通过Node节点和Thread对象协调线程的阻塞与唤醒。
摘要由CSDN通过智能技术生成

Semaphore底层原理

Semaphore就是多个线程同时跑直到state变为0则阻塞等待唤醒

Semaphore对外提供两个核心方法,一个是acquire,一个是release,内部继承了AQS的框架,实现了公平模式和非公平模式

  • acquire都会调用AQS中公共的acqureSharedInterruptibly
    public final void acquireSharedInterruptibly(int arg)
            throws InterruptedException {
   
        if (Thread.interrupted())
            throw new InterruptedException();
        if (tryAcquireShared(arg) < 0)
            //如果返回值小于0,则放入队尾并执行LockSupport的park()方法阻塞等待唤醒
            doAcquireSharedInterruptibly(arg);
    }

tryAcquireShared在公平和非公平各不相同, doAcquireSharedInterruptibly调用的共同AQS中的方法

doAcquireSharedInterruptibly的实现采用的是AQSCLH隐式双向链表队列,每个Node维护着一个Thread对象,首先将当前Node插入队尾,查看自己优先权,如果前面不是队列头部,并且当前state值是否为0,如果是则唤醒后面节点(每个Node有个next指向下个,调用LockSupport.unpark(next.thread))去唤醒,否则的话执行LockSupport.park(this)阻塞当前线程

     private Node addWaiter(Node mode) {
   
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        //队尾不为空
        if (pred != null) {
   
            //node的前驱变成tail
            node.prev = pred;
            //cas将tail设置为当前node
            if (compareAndSetTail(pred, node)) {
   
                //pred.就是之前的尾部,下一个指针指向当前node
                pred.next = node;
                return node;
            }
        }
        //如果是空,执行enq去新建立一个头和尾
        enq(node);
        return node;
    }
    private Node enq(final Node node) {
   
        for (;;) {
   
            Node t = tail;
            //如果尾是空
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值