zoukankan      html  css  js  c++  java
  • JUC(2)---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. 拿到前驱结点,根据结点的几个状态去判断前驱结点是否是取消或者其他状态,如果取消状态就剔除出去

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

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

     

  • 相关阅读:
    python学习笔记之生成器和迭代器、内置函数
    python学习笔记之装饰器(语法糖)
    python学习笔记第三天
    python学习笔记第二天
    Python学习笔记第一天
    获取系统所有软件的卸载信息
    读取注册表获取计算机上已安装程序的信息
    关机重启后运行父进程
    系统关机重启,提升进程权限
    修改用户密码
  • 原文地址:https://www.cnblogs.com/nijunyang/p/12885953.html
Copyright © 2011-2022 走看看