The simplest Semaphore was achieved by AbstractQueuedSynchronizer

Inheriting AbstractQueuedSynchronizer,

Rewrite the tryAcquireShared and tryReleaseShared methods.

import java.util.concurrent.locks.AbstractQueuedSynchronizer; public class SemaphoreTest { static class Semaphore extends AbstractQueuedSynchronizer { public Semaphore(int permits) {  setState(permits); } @Override protected int tryAcquireShared(int arg) { int available = getState(); if (available == 0) { return -1; } int left = available - 1; if (compareAndSetState(available, left)) { return left; } return -1; } @Override protected boolean tryReleaseShared(int arg) { int available = getState(); return compareAndSetState(available, available + 1); } } public static void main(String[] args) { var semaphore = new Semaphore(3); for (int i = 0; i < 1000; i++) { new Thread(() -> { semaphore.acquireShared(0); try { System.out.println("go"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } semaphore.releaseShared(0); }).start(); }}}Copy the code