Java Semaphore working principle, source code Analysis and usage examples in the contract

Source: Internet
Author: User
Tags semaphore

1. The introduction of Semaphore semaphore

We use a car park operation as an example to illustrate the role of semaphores. Suppose the car park has only three parking spaces, the first three spaces are empty. At this point, if three vehicles are coming in at the same time, the Janitor allows them to enter and put down the car block. The car that comes later must wait at the entrance until a car in the parking lot leaves. At this time, if there is a car left the parking lot, the janitor learned, open the car block, put in a car, if you leave one, then can put in a car, so reciprocating.

In this parking system, parking spaces are public resources, and each car is like a thread, and the gatekeeper acts as the semaphore. The semaphore is a nonnegative integer that indicates the available number of current public resources (in the example above can be used to compare the semaphore with an idle parking space), and when a thread is going to use a common resource (in the example above, it can use a vehicle analogy thread), first to see the semaphore, if the semaphore value is greater than 1, then minus 1, Then to occupy the public resources. If the semaphore has a value of 0, the thread blocks itself until another thread releases the public resource.

On the semaphore we define two operations: Acquire (Fetch) and release (release). When a thread invokes the acquire operation, it either succeeds in acquiring the semaphore (the semaphore minus 1), or waits until the wired path releases the semaphore or times out. Release (released) actually adds 1 to the semaphore and then wakes up the waiting thread.

Semaphores are primarily used for two purposes, one for mutual exclusion for multiple shared resources, and the other for control of the number of concurrent threads. 2. Source code Analysis of the semaphore semaphore

In Java's concurrent package, the Semaphore class represents the semaphore. Semaphore internal thread management is mainly implemented through AQS (Abstractqueuedsynchronizer). Semaphore has two constructors, the parameter permits represents the number of licenses, which is finally passed to the state value of Aqs. The thread first acquires a license at run time, if successful, the number of licenses is reduced by 1, the thread runs, and the license is released when the thread runs, and the number of licenses is 1. If the number of licenses is 0, the acquisition fails, and the thread is in the waiting queue of Aqs, and it wakes up by another thread that releases the license. You can also specify the fairness of a semaphore object when it is created. Generally, an unfair semaphore, an unfair semaphore, is an attempt to obtain a license when obtaining a license, without having to worry about whether the thread that needs to obtain the license is in the waiting queue and into row if the acquisition fails. and the fair Semaphore. When obtaining a license, first check whether the waiting queue is wired or into row.

Constructor source code

//Non-fair constructors  Public Semaphore (int permits) {    new Nonfairsync (permits);} //Determine fairness through fair parameters  Public Semaphore (intBoolean fair) {    newnew Nonfairsync (permits);}

Acquire source code

 Public voidAcquire ()throwsinterruptedexception {sync.acquiresharedinterruptibly (1);} Public Final voidAcquiresharedinterruptibly (intArgthrowsinterruptedexception {if(Thread.interrupted ())Throw NewInterruptedexception ();if(Tryacquireshared (ARG) < 0) doacquiresharedinterruptibly (ARG);}Final intNonfairtryacquireshared (intAcquires) { for(;;) {intAvailable = GetState ();intremaining = Available-acquires;if(Remaining < 0 | | Compareandsetstate (available, remaining))returnRemaining }}

As you can see, if remaining <0 is licensed, the number of licenses is less than 0, then the acquisition fails, and the thread in the Doacquiresharedinterruptibly method blocks itself and then into row.

Release source code

 Public voidRelease () {sync.releaseshared (1);} Public Final BooleanReleaseshared (intARG) {if(Tryreleaseshared (ARG)) {doreleaseshared ();return true; }return false;}protected Final BooleanTryreleaseshared (intReleases) { for(;;) {intCurrent = GetState ();intNext = current + releases;if(Next < current)//Overflow           Throw NewError ("Maximum Permit count exceeded");if(Compareandsetstate (current, next))return true; }}

You can see that the release license is adding 1 to the value of state in Aqs. The first node of the wait queue is then awakened through doreleaseshared. You can see that semaphore is using Aqs's shared mode, waiting for the first node in the queue, and if the first node succeeds in obtaining a license, it wakes up the next node, and so on.

3. Using the example
 Packagejavalearning;ImportJava.util.Random;ImportJava.util.concurrent.ExecutorService;ImportJava.util.concurrent.Executors;ImportJava.util.concurrent.Semaphore; Public classSemaphoredemo {PrivateSemaphore SMP =NewSemaphore (3);PrivateRandom rnd =NewRandom ();classTaskdemoImplementsrunnable{PrivateString ID; Taskdemo (String ID) { This. id = ID;} @Override Public voidRun () {Try{Smp.acquire (); System.out.println ("Thread"+ ID +"is working"); Thread.Sleep (Rnd.nextint ()); Smp.release (); System.out.println ("Thread"+ ID +" is Over");}Catch(Interruptedexception e) {}}} Public Static voidMain (string[] args) {Semaphoredemo Semaphoredemo =NewSemaphoredemo ();//Note the type of thread pool I created,Executorservice se = Executors.newcachedthreadpool (); Se.submit (Semaphoredemo.NewTaskdemo ("a")); Se.submit (Semaphoredemo.NewTaskdemo ("b")); Se.submit (Semaphoredemo.NewTaskdemo ("C")); Se.submit (Semaphoredemo.NewTaskdemo ("D")); Se.submit (Semaphoredemo.NewTaskdemo ("e")); Se.submit (Semaphoredemo.NewTaskdemo ("F")); Se.shutdown ();}}

Run results

Thread C is working

Thread B is working

Thread A is working

Thread C is over

Thread D is working

Thread B is over

Thread E is working

Thread A is over

Thread F is working

Thread D is over

Thread E is Over

Thread F is over

As you can see, there are up to three threads concurrently executing, and you can think of three public resources (such as the three serial ports of a computer). 4. Reference content

[1] http://my.oschina.net/cloudcoder/blog/362974

Java Semaphore working principle, source code Analysis and usage examples in the contract

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.