Talk about high concurrency (25) Parsing java.util.concurrent Components (vii) Understanding Semaphore

Source: Internet
Author: User
Tags semaphore semaphore code

The previous several analyzed the AQS principle and the realization. This is a sample of semaphore semaphore to see how Aqs is actually used.


Semaphore represents a synchronizer that can have multiple threads entering a critical section at the same time, which maintains a status indication of available tickets, and only the thread that gets the ticket can enter the critical section, otherwise it waits. Until the release of the ticket is obtained.

Semaphore is often used to manage resources in resource pools. When the state has only 2 values, it degenerates into a mutually exclusive synchronizer. Similar locks.


Take a look at the semaphore code.

It maintains an internal class sync to inherit Aqs, customizing the Tryxxx method to use Aqs.

We mentioned earlier that AQS supports both exclusive and shared modes, and semaphore is obviously a shared mode. It enables multiple threads to enter the critical section at the same time. So sync extends the method associated with GKFX.

The main operation to see Sync is a lock-free change to the state, which does not need to handle AQS queue-related operations. Talking about high concurrency (24) Parsing java.util.concurrent components (vi) in-depth understanding of Aqs (iv ) We said AQS provides a tryxxx interface to the subclass extension, which is equivalent to giving the subclass an opportunity to handle the state on its own, Determines whether to enter the synchronization queue.


1. nonfailtryacquireshared () unfair tryacquire, it immediately changed the status of the ticket, without the need to control whether there is a first-come thread is waiting, and once there is a ticket available, directly obtained the lock, do not need to enter the Aqs queue waiting for synchronization.

2. The tryreleaseshared () method is responsible for releasing the shared state of the resource, which only changes the status of the ticket. The Aqs releaseshared () method is responsible for waking up threads waiting in the Aqs queue

3. The reducepermits () and Drainpermits () methods are directly changing the state to limit the available resources

Abstract static class Sync extends Abstractqueuedsynchronizer {private static final long Serialversionuid = 119245        7210091910933L;        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 to current; }        }    }

Sync is also an abstract class, with detailed implementations of Nonfailsync and Fairsync. Represents the non-fair realization and the fair realization. As already mentioned in the previous article, the so-called unfairness simply means that there is a cut in access to resources. Enables subsequent threads to acquire resources without having to take a first-come thread in the Aqs queue. Once the acquisition fails, the Aqs queue waits, and the Aqs queue is the FIFO queue that comes first to serve.

It can be seen that Nonfailsync and Fairsync are only different in the implementation of tryacquireshared methods, others are the same.

/** * Nonfair version */static final class Nonfairsync extends Sync {private static final long Serialv        Ersionuid = -2694183684443567898l;        Nonfairsync (int permits) {super (permits);        } protected int tryacquireshared (int acquires) {return nonfairtryacquireshared (acquires); }}/** * Fair version */static final class Fairsync extends Sync {private static final long ser        Ialversionuid = 2014338818796000944L;        Fairsync (int permits) {super (permits); } protected int tryacquireshared (int acquires) {for (;;)                {if (hasqueuedpredecessors ()) return-1;                int available = GetState ();                int remaining = Available-acquires;                    if (Remaining < 0 | |            Compareandsetstate (available, remaining)) return remaining; }        }    }

Take a look at Semaphore's own approach,

1. Support for interruptible and non-disruptive access/release

2. Support Time-limited access

3. Support TRYXX Acquisition/release

4. Support to acquire/release multiple resources at the same time


Can see that the implementation of Semaphore is based on the Aqs method, the acquisition/release of a single resource is requested 1 resources, so the number of passes is 1, multiple resource gets passed an int number.

public void Acquire () throws Interruptedexception {sync.acquiresharedinterruptibly (1); }public void acquireuninterruptibly () {        sync.acquireshared (1);    }public boolean tryacquire () {        return Sync.nonfairtryacquireshared (1) >= 0;   }public boolean tryacquire (long timeout, timeunit unit)         throws Interruptedexception {         Return Sync.tryacquiresharednanos (1, Unit.tonanos (timeout));   }public void release () { & nbsp;      sync.releaseshared (1);   }public void Acquire (int permits) Throws Interruptedexception {        if (permits < 0) throw new IllegalArgumentException ();        sync.acquiresharedinterruptibly (permits);    }public void Acquireuninterruptibly (int permits) {        if (permits < 0) throw new IllegalArgumentException ();        sync.acquireshared (permits);    }public boolean tryacquire (int permits) {        if (permits < 0) throw new I Llegalargumentexception ();        return sync.nonfairtryacquireshared (permits ) >= 0;   }public boolean tryacquire (int permits, long timeout, timeunit unit)          throws Interruptedexception {        if (permits < 0) throw new IllegalArgumentException ();        return Sync.tryacquiresharednanos ( Permits, Unit.tonanos (timeout));   }public void release (int permits) {         if (permits < 0) throw new IllegalArgumentException ();        sync.releaseshared (permits);   } 

Here is an example to test the function of semaphore.

1. Create a semaphore with two notes

2. Create 20 threads to compete to run the race () method

3. In the race () method to print a sentence to wait for the resource, then get the resources, get the resources to print a word, finally release resources, release resources before printing a word

Package Com.lock.test;import Java.util.concurrent.semaphore;public class Semaphoreusecase {private Semaphore semaphore = new Semaphore (2);p ublic void Race () {System.out.println ("Thread" + thread.currentthread (). GetName () + "is Wai Ting the resource "); semaphore.acquireuninterruptibly (); Try{system.out.println (" Thread "+ thread.currentthread (). GetName () + "got the Resource"); try {thread.sleep);} catch (Interruptedexception e) {e.printstacktrace ();}} Finally{system.out.println ("Thread" + thread.currentthread (). GetName () + "is releasing the resource"); Semaphore.release ();}} public static void Main (string[] args) {final semaphoreusecase usecase = new Semaphoreusecase (), for (int i = 0; i <; I + +) {thread t = new Thread (new Runnable () {@Overridepublic void run () {Usecase.race ()}}, String.valueof (i)); T.start ();}}}

Test results:

You can see the first two lines enters upgradeable get the resources, later threads are waiting, when the thread frees the resources, the waiting threads will get the resources until they get/release the resources.

Thread 0 is waiting the Resourcethread 0 got the Resourcethread 2 is waiting the Resourcethread 2 got the Resourcethread 1 Is waiting the Resourcethread 4 is waiting the Resourcethread 3 are waiting the Resourcethread 5 is waiting the Resourceth Read 6 is waiting the Resourcethread 7 is waiting the Resourcethread 8 are waiting the Resourcethread 9 is waiting the Reso Urcethread 2 is releasing the Resourcethread 0 is releasing the Resourcethread 1 got the Resourcethread 4 got the resource Thread 1 is releasing the Resourcethread 4 is releasing the Resourcethread 3 got the Resourcethread 5 got the Resourcethre  Ad 3 is releasing the Resourcethread 5 is releasing the Resourcethread 6 got the Resourcethread 7 got the Resourcethread 7 Is releasing the Resourcethread 6 are releasing the Resourcethread 8 got the Resourcethread 9 got the Resourcethread 8 is Releasing the Resourcethread 9 is releasing the resource








Talk about high concurrency (25) Parsing java.util.concurrent Components (vii) Understanding Semaphore

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.