LockSupport and semaphore semaphore in Java

LockSupport in Java is a tool class for thread synchronization, which can be used to block and wake up threads. LockSupport controls the execution of threads by means of licenses. Each thread has a permit (permit). If the permit is available, the thread can continue to execute. If the permit is not available, the thread will be blocked and suspended.

Specifically, when the LockSupport.park() method is called, if the current thread already owns a permit, the method returns immediately. Otherwise, the thread will be blocked and suspended, waiting for the release of the license. The LockSupport.unpark(Thread t) method can be used to release the thread's license, thereby waking up the thread to continue execution.

The implementation of LockSupport is based on the underlying primitives of the operating system, using a mechanism similar to a semaphore (semaphore), so it has lower overhead and higher availability than some other thread synchronization tools (such as synchronized).

In general, LockSupport is a flexible and efficient thread synchronization tool that can well support various thread synchronization scenarios, but you need to pay attention to following some specifications and best practices when using it to avoid thread deadlock or other question.

In Java, semaphore (Semaphore) is a mechanism for multi-thread synchronization. It can limit the number of threads that access a certain resource at the same time, thereby ensuring the cooperation and synchronization between multiple threads.

Semaphore maintains a counter internally to record the number of available licenses. When a thread needs to access a resource protected by a semaphore, it must first obtain a license, that is, request a license by calling the acquire() method. If the number of licenses available at this time is greater than 0, the thread can immediately acquire the license and continue execution; otherwise, the thread will be blocked and suspended, waiting for other threads to release the license.

When a thread finishes accessing the resources protected by the semaphore, it must release the license through the release() method, so that other threads can obtain the license and continue to execute. When a license is released, the counter inside the Semaphore will increase accordingly, indicating that the number of available licenses has increased.

Semaphore also provides some other operations, such as the tryAcquire() method can try to acquire a license without being blocked, the release(int permits) method can release multiple licenses at one time, and so on.

In general, Semaphore is a very useful multi-thread synchronization mechanism that can be used to limit the number of threads that access certain resources concurrently, thereby ensuring thread safety and program correctness. However, it should be noted that some specifications and best practices should be followed when using Semaphore to avoid deadlock or other problems.

1. Example of limiting the number of threads

import java.util.concurrent.Semaphore;

public class ThreadLimitExample {
    private static Semaphore semaphore = new Semaphore(2);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " acquired semaphore");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName() + " released semaphore");
                }
            }).start();
        }
    }
}

In this example, we create a Semaphore object and set the initial number of licenses to 2. Then 5 threads are created, and the code executed by each thread is to request a license first (through the semaphore.acquire() method). If the number of available licenses is greater than 0, then the thread can acquire the license and continue to execute; otherwise, The thread will be blocked and suspended. After the execution of the thread is completed, the license needs to be released through the semaphore.release() method, so that other threads can obtain the license and continue to execute.

Since the initial number of permits is 2, only a maximum of two threads can execute concurrently. If more than two threads request a permit, the remaining threads are blocked and suspended until a thread releases the permit.

2. Example of controlling task execution order

import java.util.concurrent.Semaphore;

public class TaskSequenceExample {
    private static Semaphore semaphoreA = new Semaphore(1);
    private static Semaphore semaphoreB = new Semaphore(0);
    private static Semaphore semaphoreC = new Semaphore(0);

    public static void main(String[] args) {
        new Thread(() -> {
            try {
                semaphoreA.acquire();
                System.out.println("Thread 1 running");
                Thread.sleep(1000);
                semaphoreB.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                semaphoreB.acquire();
                System.out.println("Thread 2 running");
                Thread.sleep(1000);
                semaphoreC.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                semaphoreC.acquire();
                System.out.println("Thread 3 running");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        semaphoreA.release();
    }
}

In this example, we create three Semaphore objects, which respectively represent the execution order of the three tasks. Initially, the number of licenses for semaphoreA is 1, and the number of licenses for semaphoreB and semaphoreC is 0. This ensures that the first task can be executed first, while the other two tasks need to wait for the first task to complete before continuing.

In the main thread, we start three threads, corresponding to three tasks. The code executed by each thread is first passed through

おすすめ

転載: blog.csdn.net/Jinliang_890905/article/details/130189231