如何在并发Java应用程序中使用计数信号量?
Java Counting Semaphore 维护指定数量的pass 或权限,Current Thread 必须获得访问共享资源的许可。如果许可已经被其他线程耗尽,则它可能会等待,直到由于从各个线程释放许可而导致许可变得可用。此并发实用程序对于实现生产者-消费者设计模式或实现有限的资产池(例如线程池、数据库连接池等)非常有用。 Java.util.Semaphore类是一个用数字初始化的计数信号量的权限。
信号量提供了两种主要的获取许可和释放许可的方法
- Acquire( ):如果有一个许可,该方法获取一个许可,并立即返回,将可用许可的数量减少一个。如果当前线程在等待许可时被中断,则抛出 InterruptedException。
- release() :此方法获取给定数量的许可,如果它们可用,并立即返回,将可用许可的数量减少给定的数量。如果当前线程在等待许可时被中断,则抛出 InterruptedException。
执行:
二元信号量被称为具有一个许可的计数信号量,因为它只有两个状态许可可用或不可用。要执行只允许一个线程执行的互斥或临界区,可以使用二进制信号量。线程在acquire() 上等待,直到线程通过在信号量上调用release() 允许在临界区中释放。下面是Java信号量计数,其中二进制信号量用于提供对基本代码部分的共享独占访问
例子:
Java
// Java Program to illustrate use Counting Semaphore
// in Concurrent Java Application
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
// Initialize the semaphore with the number
// of permits required
// Here only 1 permit is allowed
Semaphore binary = new Semaphore(1);
// Main driver method
public static void main(String args[])
{
final SemaphoreTest test = new SemaphoreTest();
// Thread 1
new Thread() {
// Method that should be executed for thread1
@Override public void run()
{
test.mutualExclusion();
}
}.start();
// Thread 2
new Thread() {
// Method that should be executed for thread2
@Override public void run()
{
test.mutualExclusion();
}
}.start();
}
// Method
private void mutualExclusion()
{
// Try block to check for exceptions
try {
// acquire() acts as an input to semaphore
// to check for available permits
binary.acquire();
// Mutual exclusive region
System.out.println(
Thread.currentThread().getName()
+ " inside mutual exclusive ");
// sleep() method is used to hold thread for
// sometime Parameter is nanoseconds to be
// holded
Thread.sleep(1000);
}
// Catch block to handle the exception
// Handling exception if thread is interrupted
// either before or during the activity
catch (InterruptedException e) {
// Print and display the line number where
// exception occured
e.printStackTrace();
}
finally {
// release() method acts as output to semaphore
// When thread operation is completed
// release() method increase the permits
// in the semaphore
binary.release();
// Printing the thread name
// using the getName() method
System.out.println(
Thread.currentThread().getName()
+ " outside of mutual exclusive ");
}
}
}
输出
Thread-0 inside mutual exclusive
Thread-1 inside mutual exclusive
Thread-0 outside of mutual exclusive
Thread-1 outside of mutual exclusive