视频课程
小黑屋思过中,禁止观看!
评论并刷新后可见

您需要在视频最下面评论并刷新后,方可查看完整视频

视频课程
立即观看
付费视频

您支付费用,方可查看完整视频

¥{{user.role.value}}
课程视频
开始学习
会员专享

视频合集

Semaphore实现详解,核心源码剖析!

  • 课程笔记
  • 问答交流

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,也是常用的并发工具之一,它常常用于流量控制。

通常情况下,公共的资源常常是有限的,例如数据库的连接数。

使用Semaphore可以帮助我们有效的管理这些有限资源的使用。

为了助大家掌握好Semaphore,本节课程我重点讲解以下6点:

1.Semaphore的简介

2.Semaphore的核心成员

3.Semaphore的构造函数

4.Semaphore的核心源码

5.Semaphore的应用场景

6.Semaphore的总结

Semaphore

Semaphore的结构和ReentrantLock以及CountDownLatch很像,内部采用了公平锁与非公平锁两种实现,如果你已经看过了ReentrantLock源码分析CountDownLatch源码分析,弄懂它将毫不费力。

Semaphore的核心成员

与CountDownLatch类似,Semaphore主要是通过AQS的共享锁机制实现的,因此它的核心属性只有一个sync,它继承自AQS
Semaphore实现详解,核心源码剖析!-mikechen

Sync的源码如下:

abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = 1192457210091910933L;

        Sync(int permits) {
            setState(permits);
        }

        final int getPermits() {
            return getState();
        }

        final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

        protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current) // overflow
                    throw new Error("Maximum permit count exceeded");
                if (compareAndSetState(current, next))
                    return true;
            }
        }

        final void reducePermits(int reductions) {
            for (;;) {
                int current = getState();
                int next = current - reductions;
                if (next > current) // underflow
                    throw new Error("Permit count underflow");
                if (compareAndSetState(current, next))
                    return;
            }
        }

        final int drainPermits() {
            for (;;) {
                int current = getState();
                if (current == 0 || compareAndSetState(current, 0))
                    return current;
            }
        }
    }

 

Semaphore的构造函数

有两个构造函数:

public Semaphore(int permits) {
    sync = new NonfairSync(permits);
}


public Semaphore(int permits, boolean fair) {
    sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

默认的构造函数使用的是非公平锁,另一个构造函数通过传入的fair参数来决定使用公平锁还是非公平锁,这一点和ReentrantLock用的是同样的套路,都是同样的代码框架。

Semaphore的核心方法

Semaphore实现详解,核心源码剖析!-mikechen

评论交流
  1. kaka

    陈老师您好,下面这个代码没看太懂,sync是个类怎么会等于一个布尔值呢?该怎么理解这句代码呢?
    public Semaphore(int permits, boolean fair) {
    sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

    • mikechen

      这段代码是Semaphore的构造函数,sync后面的fair是用于参数判断,用于判断是公平还是非公平,比如true就走公平锁FairSync的这个逻辑,如果你传参是false就走NonfairSync非公平锁的逻辑。
      one more,貌似你没有加我微信呢,我的微信:mikechenrui