Semaphore是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理使用公共资源。
    可以用于流量控制,特别是公用资源有限的应用场景,比如数据库连接。
    Semaphore的用法很简单,首先线程使用acquire()方法获取一个许可证,使用完之后调用release()方法归还许可证。还可以用tryAcquire()方法尝试获取许可证。

    acquire()方法最后的实现逻辑分公平锁和非公平锁

    1. //公平锁的获取方式
    2. protected int tryAcquireShared(int acquires) {
    3. //自旋尝试获取共享锁
    4. for (;;) {
    5. //是否有线程在等待,有就返回失败
    6. if (hasQueuedPredecessors())
    7. return -1;
    8. int available = getState();
    9. int remaining = available - acquires;
    10. //还有许可证,并且同步状态修改成功,返回剩余许可数
    11. if (remaining < 0 ||
    12. compareAndSetState(available, remaining))
    13. return remaining;
    14. }
    15. }
    16. //不公平锁的获取方式,区别就在于不再判断是否有线程在等待,而是直接尝试获取许可
    17. final int nonfairTryAcquireShared(int acquires) {
    18. for (;;) {
    19. int available = getState();
    20. int remaining = available - acquires;
    21. if (remaining < 0 ||
    22. compareAndSetState(available, remaining))
    23. return remaining;
    24. }
    25. }
    1. //释放锁
    2. protected final boolean tryReleaseShared(int releases) {
    3. for (;;) {
    4. int current = getState();
    5. int next = current + releases;
    6. if (next < current) // overflow
    7. throw new Error("Maximum permit count exceeded");
    8. if (compareAndSetState(current, next))
    9. return true;
    10. }
    11. }

    其他一些方法:
    int availablePermits();返回此信号量中当前可用的许可证数
    int getQueueLength();返回正在等待获取许可证的线程数
    Boolean hasQueuedThreads();是否有线程正在等待获取许可证
    void reducePermits();减少reduction个许可证,是protected方法
    collection getQueuedThreads();返回所有等待获取许可证的线程集合,是个protected方法