In multi-threaded programming, it is often necessary to limit the number of threads that can access a resource or block of code at any given time. This is known as concurrency control.
One way to achieve concurrency control in Java is to use the java.util.concurrent.Semaphore
class.
A semaphore is a token that allows a thread to enter a critical section, which is a block of code that can only be executed by one thread at a time. When the thread exits the critical section, it returns the semaphore to the pool.
A semaphore can be used to control access to any resource, not just code. For example, a semaphore can be used to control access to a printer or database.
A semaphore is created by specifying the number of permits. This is the number of threads that can access the critical section at the same time. For example, to create a semaphore with 10 permits:
Semaphore semaphore = new Semaphore(10);
A thread requests a permit by calling the acquire()
method. This method blocks the thread until a permit is available. For example:
semaphore.acquire();
When a thread exits the critical section, it calls the release()
method to return the permit to the semaphore. For example:
semaphore.release();
The following example shows how to use a semaphore to control access to a printer.
import java.util.concurrent.Semaphore;
public class Printer {
private Semaphore semaphore;
public Printer(int numPermits) {
semaphore = new Semaphore(numPermits);
}
public void print(String document) {
try {
semaphore.acquire();
// print the document
} catch (InterruptedException e) {
// handle error
} finally {
semaphore.release();
}
}
}
In this example, the print()
method acquires a permit before printing the document. If no permits are available, the acquire()
method blocks the thread until one is available. After printing the document, the release()
method returns the permit to the semaphore.
Semaphores and locks are both mechanisms for concurrency control. However, there are some key differences between them.
Java's java.util.concurrent.Semaphore
class provides a mechanism for concurrency control. Semaphores can be used to control access to any resource, not just code. When using semaphores, it is important to remember the differences between semaphores and locks.