Brief introduction
Let's take a hotel as an example. Let's assume that there are only three seats in a hotel. At first, all three seats are empty. At this time, if three guests come at the same time, the waiter allows them to go in for dinner, and then tells the public that there are no seats available. Later guests had to wait at the door until someone left. At this time, if a guest leaves, the waiter tells the guest that he can come in for dinner, and if another guest leaves, he can come in for dinner, so to and fro.
In this hotel, seats are public resources. Everyone is like a thread. The waiter acts as a semaphore. A semaphore is a non-negative integer representing the number of currently available public resources (in the example above, a free seat can be used to analogize semaphores). When a thread wants to use public resources (in the example above, a guest can be used to compare threads), it first looks at the semaphore, if the value of the semaphore is greater than 1, it is subtracted by 1, and then it occupies the public resources. If the semaphore value is 0, the thread will block itself until other threads release common resources.
1. A brief introduction to Semaphore
a. It can be used to control the number of threads accessing specific resources at the same time, so as to coordinate the work of threads.
b. A virtual resource pool is maintained. If the license is 0, the thread will block and wait until the license is greater than 0, then it will have the opportunity to obtain the license again.
c. There are static internal classes with fair and unfair locks to access resources.
2. Semaphore method
A, public Semaphore(int permits); // Create a semaphore object with a given number of licenses and acquire resources by default in an unfair lock manner
b, public Semaphore(int permits, boolean fair); // Create a semaphore object with a given number of permissions, and the fairness is determined by the value of the fairboolean parameter passed in.
c, public void acquire(); // From this semaphore, get a license, and block waiting when the number of licenses is less than zero
d, public void acquire(int permits); // From this semaphore get permits license, when the number of licenses is less than zero, block waiting, but when the blocked waiting thread is awakened and found interrupted, throw the InterruptedException exception.
e, public void acquire Uninterruptibly (int permits); from this semaphore obtain permits licenses, when the number of licenses is less than zero, block waiting, but when the blocked waiting thread is awakened and found interrupted, the InterruptedException exception will not be thrown.
f, public void release();// release a license
g, public void release(int permits); release permits
The above is just a list of the main method names. The method is explained in detail. The Semaphore class has comments on it. Not one by one tired out.
Give us a simple example to help us deepen our impression.
/**
* @author shuliangzhao
* @Title: SemaPhoreTest
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/5 22:50
*/
public class SemaPhoreTest {
private Semaphore semaphore = new Semaphore(3);
class TaskThread implements Runnable{
private int id;
public TaskThread(int id) {
this.id = id;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("Thread " + id + " is working");
Thread.sleep(2000);
semaphore.release();
System.out.println("Thread " + id + " is over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SemaPhoreTest semaPhoreTest = new SemaPhoreTest();
/*for (int i = 0;i<6;i++) {
Thread thread = new Thread(semaPhoreTest.new TaskThread(i));
thread.start();
}*/
ExecutorService executorService = Executors.newCachedThreadPool();//Synchronized queue threads
executorService.submit(semaPhoreTest.new TaskThread(1));
executorService.submit(semaPhoreTest.new TaskThread(2));
executorService.submit(semaPhoreTest.new TaskThread(3));
executorService.submit(semaPhoreTest.new TaskThread(4));
executorService.submit(semaPhoreTest.new TaskThread(5));
executorService.submit(semaPhoreTest.new TaskThread(6));
executorService.submit(semaPhoreTest.new TaskThread(7));
executorService.shutdown();
}
}
Operation results