• 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方法,去唤醒队列中等待的线程,获取到许可执行

     

  • 相关阅读:
    android Scroller类的理解
    android 小方法
    android 小知识点
    【转】Android TouchEvent事件传递机制
    android 自定义控件二之仿QQ长按删除
    android ExpandAbleListView控件
    android AChartEngine图标引擎
    2018.11.07-1117-无序字母对 character
    2018.11.07-4031-reverse
    2018.11.07-1015-幸运字符串查询 (lucky)
  • 原文地址:https://www.cnblogs.com/nijunyang/p/12885953.html
Copyright © 2020-2023  润新知