Introduction of Semaphore
Public class SemaphoreDemo {public static void main(String[] args) {final Semaphore Semaphore = new Semaphore(3, true); new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(); Thread.sleep(200); System.out.println(thread.currentThread ().getid () + "running "); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(3); Thread.sleep(200); System.out.println(thread.currentThread ().getid () + "running "); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(3); } } }).start(); new Thread(new Runnable() { @Override public void run() { try { semaphore.acquire(2); Thread.sleep(200); System.out.println(thread.currentThread ().getid () + "running "); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(2); } } }).start(); }}Copy the code
-
Semaphore: A Semaphore that inherits AQS using its shared mode and initializes its state value to represent the resource value
-
Acquire (n): If the state value is reduced by n, resources are obtained
-
Release (n): add state to n, and the resource is released on success
Take the fair semaphore as an example to parse the Acquire () process
-
A fair semaphore is different from an unfair semaphore: an unfair semaphore directly attempts to acquire a resource, whereas a fair semaphore looks to see if a thread is waiting on the blocking queue
-
Fair and unfair semaphores are the same :release() is the same
public void acquire() throws InterruptedException { sync.acquireSharedInterruptibly(1); } / / AQS acquireSharedInterruptibly () public final void acquireSharedInterruptibly (int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); If (tryAcquireShared(arg) < 0) if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); Protected int tryAcquireShared(int acquires) {for (;) {// Whether a thread waits on the blocking queue: see AQS source Read (a) if (Hasqueued24 () return -1; Int available = getState(); int available = getState(); Int remaining = available - acquires; // Remaining: remaining value int remaining = available - acquires; / / remaining < 0: semaphore resources value, to obtain failure / / compareAndSetState () : the CAS operation set the state value if (remaining < 0 | | compareAndSetState (available, remaining)) return remaining; }}Copy the code
Parse the Release () process
public void release() { sync.releaseShared(1); } //AQS releaseShared() public final Boolean releaseShared(int arg) {//Semaphore overwrite this method (tryReleaseShared(arg)) {// Wake up the blocking queue thread, see AQS source reading (3); return true; } return false; } // Protect final Boolean tryReleaseShared(int Releases) {for (;) {////AQS state value int current = getState(); // Release resource state int next = current + releases; // overflow throw new Error("Maximum permit count exceeded"); // overflow throw new Error("Maximum permit count exceeded"); If (compareAndSetState(current, next)) return true; }}Copy the code