📜  如何在并发Java应用程序中使用计数信号量?

📅  最后修改于: 2022-05-13 01:54:41.907000             🧑  作者: Mango

如何在并发Java应用程序中使用计数信号量?

Java Counting Semaphore 维护指定数量的pass 或权限,Current Thread 必须获得访问共享资源的许可。如果许可已经被其他线程耗尽,则它可能会等待,直到由于从各个线程释放许可而导致许可变得可用。此并发实用程序对于实现生产者-消费者设计模式或实现有限的资产池(例如线程池、数据库连接池等)非常有用。 Java.util.Semaphore类是一个用数字初始化的计数信号量的权限。

如何在并发 Java 应用程序中使用计数信号量?

信号量提供了两种主要的获取许可和释放许可的方法

  • 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