Preface
In Java, Semaphore is a commonly used synchronization tool that can be used to control the number of accesses to shared resources. Semaphores are mainly used for two purposes: one is for the mutually exclusive use of multiple shared resources, and the other is for the control of the number of concurrent threads. Although JavaPackage provided
Semaphore
class, but understanding how to manually implement a semaphore can help to have a deeper understanding of the principles of concurrent programming.
Below, we will useSynchronized
Keywords to implement a simple semaphore. Our goal is to implement a counting semaphore, where the count of the semaphore indicates the number of threads that can access a certain resource simultaneously.
Implementing the basic framework
First, we define aSemaphore
class, it needs to maintain a counter to track the number of available licenses. The initial value of the counter is provided by the constructor when the semaphore is created.
public class SimpleSemaphore { private int signals = 0; private int bound = 0; public SimpleSemaphore(int upperBound) { = upperBound; } }
Implement acquire method
acquire
Method is used to obtain a license. If there is currently no license available (i.e.signals
Equal to the upper boundbound
), then the method will block until a license is available.
public synchronized void acquire() throws InterruptedException { while (signals == bound) { wait(); } signals++; notify(); }
Used heresynchronized
Keywords to ensure that the method is thread-safe. ifsignals
achievebound
, callwait()
Make the current thread wait untilsignals
Reduce and continue to execute. Each callacquire
When the method,signals
They will increase and passnotify()
Wake up the thread that may be waiting.
Implement the release method
release
Methods are used to release a license, increasing the number of available licenses. If there are threads waiting for permission, one of the threads will be awakened.
public synchronized void release() throws InterruptedException { while (signals == 0) wait(); signals--; notify(); }
Similarly, usesynchronized
Ensure thread safety and pass after the license is releasednotify()
Wake up the thread that may be waiting for.
Example usage
Here's how to use itSimpleSemaphore
A simple example of .
public class Main { public static void main(String[] args) { SimpleSemaphore semaphore = new SimpleSemaphore(3); // Allow 3 threads to access simultaneously Runnable longRunningTask = () -> { try { (); ("Thread " + ().getId() + " is running"); // Simulate long-term tasks (2000); (); ("Thread " + ().getId() + " is finished"); } catch (InterruptedException e) { (); } }; for (int i = 0; i < 10; i++) { new Thread(longRunningTask).start(); } } }
In this example, we created a 3 licenseSimpleSemaphore
, then 10 threads were started to perform a long-running task. Due to semaphore limitations, these 10 threads will be executed in batches (3 per batch).
Summarize
By usingsynchronized
Keywords,wait()
andnotify()
Method, we can manually implement a simple semaphore. This implementation provides mutex access and coordination between threads. Although JavaSemaphore
Classes provide more advanced functionality, but manually implementing semaphores is a good exercise in understanding concurrency control. Remember that concurrency tools in the Java standard library should be preferred in real environments because they have been tested more widely and are better optimized.
The above is the detailed content of the method of using the synchronized keyword to implement semaphores. For more information about synchronized semaphores, please pay attention to my other related articles!