Reference: Http://ifeve.com/concurrency-semaphore/
Https://www.cnblogs.com/feijishuo/p/4538814.html
https://zhuanlan.zhihu.com/p/29463581
Brief Introduction
Semaphore (semaphores) are used to control the number of threads that access a particular resource at the same time, by coordinating each thread to ensure proper use of public resources. For many years, I felt it was literally hard to understand the meaning of Semaphore's expression, can only compare it to control traffic traffic lights, such as XX Road to limit traffic, only allow 100 vehicles at the same time to exercise on this road, the other must be waiting at the intersection, so the first 100 cars will see the green light, Can enter this road, the car behind will see a red light, can not drive into XX Road, but if the first 100 of the five vehicles have left the XX road, then allow 5 vehicles to enter the road behind, this example is the car is a thread, the road to enter a thread in the execution, leaving the road to express the completion of the execution of the thread, Seeing a red light means that the thread is blocked and cannot be executed. Application Scenarios
Semaphore can be used for traffic control, especially for limited public resource applications, such as database connections. If there is a requirement to read tens of thousands of files of data, because are IO-intensive tasks, we can start dozens of threads concurrent read, but if you read the memory, you also need to store in the database, and the number of database connections only 10, At this point we have to control only 10 threads at the same time get the database connection to save the data, otherwise it will not get the database connection. This time, we can use semaphore to do flow control.
The Semaphore class, located under the Java.util.concurrent package, provides 2 constructors:
The public semaphore (int permits) { //parameter permits indicates the number of licenses, that is, how many threads can be allowed to access
sync = new Nonfairsync (permits) at the same time;
}
Public semaphore (int permits, Boolean fair) { //This one more parameter fair to indicate whether it is fair, that is, the longer the wait time to obtain the license
sync = (FAIR)? New Fairsync (permits): New Nonfairsync (permits);
}
Here are some of the more important methods in the semaphore class, first, the Acquire (), Release () method:
public void Acquire () throws Interruptedexception { } //Get a licensed public
void acquire (int permits) throws interruptedexception {} //Get permits license public
void release () {} //Free a licensed public
void (int Permits) {} //release permits license
Acquire () is used to obtain a license and, if not licensed, will wait until the license is granted.
Release () is used to free the license. Note that prior permission must be granted before releasing the license.
These 4 methods are blocked, and you can use the following methods if you want to get the execution results immediately:
public Boolean Tryacquire () {}; Attempt to obtain a license that returns true immediately if it succeeds, and returns false public
Boolean tryacquire (Long timeout, timeunit) immediately if a failure is obtained throws interruptedexception {}; Attempts to obtain a license that returns true immediately if it succeeds within a specified time, or returns False public
Boolean tryacquire (int permits) {};//attempt to obtain a permits license. Returns true immediately if successful, returns false public
Boolean tryacquire (int permits, long timeout, timeunit unit) If a failure is obtained throws interruptedexception {}; Attempt to obtain a permits license, return true immediately if successful within a specified time, or return false immediately
If a factory has 3 machines, but there are 8 workers, a machine can only be used by one worker and the other workers will continue to use it. Then we can make it through semaphore:
Import Java.util.Random;
Import Java.util.concurrent.Semaphore; /** * If a factory has 5 machines, but there are 8 workers, a machine can only be used by one worker, and the other workers can continue to use it only if they have finished using it.
Then we can implement it through Semaphore: */public class Test {public static void main (string[] args) throws Interruptedexception { int N = 8; Number of workers semaphore semaphore = new semaphore (5);
Number of machines for (int i = 1; I <= N; i++) {int j = i; New Thread (New Runnable () {@Override public void run () {try {System.out.println) (System.currentt
Imemillis () + ". Worker" + j + "Wait for machine ...");
Semaphore.acquire ();
Long start = System.currenttimemillis ();
System.out.println (start+ ". Worker" + j + "get a machine in production ...");
Thread.Sleep (New Random (). Nextint (3000));
Long end = System.currenttimemillis ();
System.out.println (end+ ". Worker" + j + "releases the machine.)" + (End-start));
Semaphore.release ();
catch (Interruptedexception e) {e.printstacktrace ();
}}). Start ();
Thread.Sleep (1); }
}
}
Output:
1524641499785. Workers 1 wait for the machine ...
1524641499786. Workers 1 get a machine in production ...
1524641499786. Workers 2 wait for the machine ...
1524641499786. Workers 2 get a machine in production ...
1524641499787. Workers 3 wait for the machine ...
1524641499787. Workers 3 Get a machine in production ...
1524641499788. Workers 4 wait for the machine ...
1524641499789. Workers 5 wait for the machine ...
1524641499790. Workers 6 wait for the machine ...
1524641499791. Workers 7 wait for the machine ...
1524641499792. Workers 8 wait for the machine ...
1524641500793. Workers 2 Release the machine. Spents 1007
1524641500793. Workers 4 get a machine in production ...
1524641500971. Workers 1 Release the machine. Spents 1185
1524641500971. Workers 5 get a machine in production ...
1524641501500. Workers 4 Release the machine. Spents 707
1524641501500. Workers 6 get a machine in production ...
1524641501667. Workers 3 Release the machine. Spents 1880
1524641501667. Workers 7 get a machine in production ...
1524641502187. Workers 6 Release the machine. Spents 687
1524641502187. Workers 8 get a machine in production ...
1524641503211. Workers 7 release the machine. Spents 1544
1524641503440. Workers 5 Release the machine. Spents 2469
1524641504493. Workers 8 Release the machine. Spents 2306
New Semaphore (3) and new Semaphore (3, true) are both fair and unfair, and the threads are executed sequentially. It makes me wonder if, in an unfair situation, a thread should be preempted, that is, execution is not necessarily performed sequentially, but the test results are not.