Semaphore和AQS

Posted nijunyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Semaphore和AQS相关的知识,希望对你有一定的参考价值。

Semaphore意思的信号量,它的作用是控制访问特定资源的线程数量

构造方法

public Semaphore(int permits)

public Semaphore(int permits, boolean fair)

  permits:允许同时访问的线程数量

  fair:是否公平,若true的话,下次执行的会是先进去等待的线程(先入先出)

 

使用

acquire():获取许可执行

release():释放许可,让其他线程获取许可执行。

 

显然这个功能可以用于资源访问控制或者是限流的操作。

 

如下代码每次只会有两个线程执行。

package com.nijunyang.concurrent;

import java.util.concurrent.Semaphore;

/**
 * Description:
 * Created by nijunyang on 2020/5/13 23:31
 */
public class SemaphoreTest {
    Semaphore semaphore;

    public SemaphoreTest(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    public static void main(String[] args) {
        SemaphoreTest semaphoreTest = new SemaphoreTest(new Semaphore(2, true));
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(() -> {
                try {
                    semaphoreTest.test();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "线程" + i);
            thread.start();
        }
        System.out.println("线程创建完毕.");
    }

    public void test() throws InterruptedException {
        semaphore.acquire();
        System.out.println(Thread.currentThread().getName() + "执行.");
        Thread.sleep(4000);
        semaphore.release();
    }
}

 

原理

进入Semaphore的代码一看,又见到AQS,前面ReentrantLock中用到的是独占模式,Semaphore中就是共享模式了。和ReentrantLock如出一辙,内部类Sync继承了AbstractQueuedSynchronizer,同时有两个子类实现一个公平FairSync,另一个非公平NonfairSync

构造方法传入的permits,最终会赋值到AbstractQueuedSynchronizerstate字段,这个字段的ReentrantLock中是用来计算锁重入的。但是在Semaphore里面字段是用来控制资源访问数量的。

 

1.acquire方法获取的许可的时候 先去扣减,将state的值-1,如果结果不小于0,就通过CAS操作修改state的值,最后返回当前剩余许可

技术图片

 

 

 2. 如果返回的许可剩余数量小于0 就执行doAcquireSharedInterruptibly方法,将当前线程以共享的模式加入到队列中去,再将线程挂起

技术图片

 

技术图片

 

3.release方法 释放许可  CAS操作将state的值+1

技术图片

 

 4.设置成功了执行doReleaseShared方法,去唤醒队列中等待的线程,获取到许可执行

技术图片

 

 技术图片

 

以上是关于Semaphore和AQS的主要内容,如果未能解决你的问题,请参考以下文章

Semaphore和AQS

Semaphore 源码解读

基于 AQS 的并发编程: CountDownLatch 和 semaphore

多线程(十三AQS原理-Semaphore信号量)

AQS源码探究_09 Semaphore源码分析

AQS源码探究_09 Semaphore源码分析