concept

Semaphores are primarily used for two purposes

  • One is for mutually exclusive use of shared resources
  • Another control for the number of concurrent threads

code

Let’s simulate a parking scramble. Let’s say there are six cars and three parking Spaces

So we first need to define the semaphore to be 3, which is 3 parking Spaces

/** * initializes a semaphore with 3. The default is false for non-fair locking, simulating 3 parking Spaces */
Semaphore semaphore = new Semaphore(3.false);
Copy the code

Then we simulate six cars competing for a parking space simultaneously, but the semaphore needs to be reduced by one after the first car is competing for a parking space

// Represents a car that has occupied the parking space
semaphore.acquire(); / / to grab
Copy the code

At the same time, the vehicle is assumed to wait 3 seconds before releasing the semaphore

// Each car stops for 3 seconds
try {
	TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
	e.printStackTrace();
}
Copy the code

Finally the vehicle leaves, releasing the semaphore

Semaphore.release ();Copy the code

The complete code

package com.company;

import sun.awt.windows.ThemeReader;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo {
    public static void main(String[] args) {
        /** * initializes a semaphore with 3. The default is false for non-fair locking, simulating 3 parking Spaces */
        Semaphore semaphore = new Semaphore(3.false);
        // Simulate 6 cars
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    // Represents a car that has occupied the parking space
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t grabs a parking space");
                    // Each car stops for 3 seconds
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "\t leave parking space");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    // Release the parking spacesemaphore.release(); } },String.valueOf(i)).start(); }}}Copy the code

The results

2Get the car0Get the car1Get the car0Leave the parking space2Leave the parking space1Leave the parking space4Get the car3Get the car5Get the car4Leave the parking space5Leave the parking space3Leave the carCopy the code

If we look at the operation results, we can find that the 201 vehicles first grabbed the parking space, then waited for 3 seconds, then left, and then the 3, 4 and 5 behind grabbed the parking space again

Principle:

semaphore.acquire(); Get, assume if it’s full, wait, wait to be released! semaphore.release(); Release, will release the current semaphore + 1, and then wake up the waiting thread!

Function: Multiple shared resources mutually exclusive use! Concurrent flow limiting, control the maximum number of threads!