无论是Semaphore还是CountDonwLatch或者是CyclicBarrier,其实我们都可以通过Lock接口+Condition条件队列功能来模拟实现,但是不够抽象所以才出现了AQS这个抽象的面向开发者同步框架,比如这个Semaphore,我们看下如果使用Lock实现:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MySemaphore {
    private final Lock lock = new ReentrantLock(true);
    private final Condition condition = lock.newCondition();
    private int permit;

    public MySemaphore(int permit) {
        this.permit = permit;
    }

    private void acquire() {
        lock.lock();
        try {
            if (permit == 0) {
                condition.await();// 如果超过限制,就进入条件阻塞队列
            }
            System.out.println(Thread.currentThread().getName() + "获得资源 ");
            permit--;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private void release() {
        lock.lock();
        try {
            permit++;
            condition.signalAll(); // 每当有一个释放令牌,就唤醒所有等待的线程}finally {
            lock.unlock();
        } finally {
            lock.unlock();
        }
    }
}