• 并发编程学习笔记(十八、Semaphore源码分析)


    目录:

    • Semaphore简介
    • 内部类(Sync、NonfairSync、FairSync)
    • 属性及构造器
    • 其它方法

    Semaphore简介

    Semaphore是信号量,它是synchronized的加强版,作用是控制线程的并发数量。就这一点而言,单纯的synchronized关键字是实现不了的。

    内部类(Sync、NonfairSync、FairSync)

    1、Sync:

     1 abstract static class Sync extends AbstractQueuedSynchronizer {
     2     private static final long serialVersionUID = 1192457210091910933L;
     3 
     4     /**
     5      * Sync构造函数,用于初始化许可证数量
     6      */
     7     Sync(int permits) {
     8         setState(permits);
     9     }
    10 
    11     final int getPermits() {
    12         return getState();
    13     }
    14 
    15     /**
    16      * 非公平锁的共享实现
    17      */
    18     final int nonfairTryAcquireShared(int acquires) {
    19         for (;;) {
    20             int available = getState();
    21             // 剩余许可证数量,每次加锁成功将其减少
    22             int remaining = available - acquires;
    23             // 当许可证数量小于0 || CAS将实际许可证数量更新成剩余许可证数量
    24             if (remaining < 0 ||
    25                 compareAndSetState(available, remaining))
    26                 return remaining;
    27         }
    28     }
    29 
    30     /**
    31      * 释放资源的共享实现(增加许可证数量)
    32      */
    33     protected final boolean tryReleaseShared(int releases) {
    34         for (;;) {
    35             int current = getState();
    36             // 获取拥有许可证数量(当前剩余 + 释放数量)
    37             int next = current + releases;
    38             if (next < current) // overflow
    39                 throw new Error("Maximum permit count exceeded");
    40             // CAS更新拥有许可证数量
    41             if (compareAndSetState(current, next))
    42                 return true;
    43         }
    44     }
    45 
    46     /**
    47      * 减少许可证数量
    48      */
    49     final void reducePermits(int reductions) {
    50         for (;;) {
    51             int current = getState();
    52             int next = current - reductions;
    53             if (next > current) // underflow
    54                 throw new Error("Permit count underflow");
    55             if (compareAndSetState(current, next))
    56                 return;
    57         }
    58     }
    59 
    60     /**
    61      * 获取剩余许可证数量
    62      */
    63     final int drainPermits() {
    64         for (;;) {
    65             int current = getState();
    66             if (current == 0 || compareAndSetState(current, 0))
    67                 return current;
    68         }
    69     }
    70 }

    2、NonfairSync:

     1 static final class NonfairSync extends Sync {
     2     private static final long serialVersionUID = -2694183684443567898L;
     3 
     4     NonfairSync(int permits) {
     5         super(permits);
     6     }
     7 
     8     protected int tryAcquireShared(int acquires) {
     9         return nonfairTryAcquireShared(acquires);
    10     }
    11 }

    3、FairSync:

     1 static final class FairSync extends Sync {
     2     private static final long serialVersionUID = 2014338818796000944L;
     3 
     4     FairSync(int permits) {
     5         super(permits);
     6     }
     7 
     8     protected int tryAcquireShared(int acquires) {
     9         for (;;) {
    10             // 公平锁的唯一区别就是只有当不存在等待时间比你长的线程时才会加锁,否则返回-1
    11             if (hasQueuedPredecessors())
    12                 return -1;
    13             int available = getState();
    14             int remaining = available - acquires;
    15             if (remaining < 0 ||
    16                 compareAndSetState(available, remaining))
    17                 return remaining;
    18         }
    19     }
    20 }

    属性及构造器

    1、属性:

    1 private final Sync sync;

    2、构造器:

    1 public Semaphore(int permits) {
    2     sync = new NonfairSync(permits);
    3 }
    4 
    5 public Semaphore(int permits, boolean fair) {
    6     sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    7 }

    构造器同ReentrantLock,默认非公平实现方式。

    其它方法

    其它的一些函数都比较简单,只要你把之前的AQS看懂你就可以很轻松的了解。

    如:

    • java.util.concurrent.Semaphore#acquire();
    • java.util.concurrent.Semaphore#acquire(int);
    • java.util.concurrent.Semaphore#release();
    • 等等。
  • 相关阅读:
    mybatis 查询list,内容为null,但list的size 为1
    mysql 父子表 注意事项
    导入
    php生成签名及验证签名
    PHP通过OpenSSL生成证书、密钥并且加密解密数据,以及公钥,私钥和数字签名的理解
    PHP 做 RSA 签名 生成订单(支付宝例子)
    接口安全调用该怎么做?签名?证书?服务安全?
    PHP 以POST方式提交XML、获取XML,最后解析XML
    php 解析xml 的四种方法
    php 模拟POST提交的2种方法
  • 原文地址:https://www.cnblogs.com/bzfsdr/p/13192768.html
Copyright © 2020-2023  润新知