# Java 信号量示例

> 原文： [https://javatutorial.net/java-semaphore-example](https://javatutorial.net/java-semaphore-example)

信号量可用于限制并发线程的数量，并且实质上，此类维护一组许可。

`acquire()`从信号量获取许可，然后`release()`将许可返回信号量。 如果没有许可证，则`acuire()`将阻塞直到可用

信号量用于控制对特定资源的访问。

![java-featured-image](img/e0db051dedc1179e7424b6d998a6a772.jpg)

**工作流程**

信号量设置为一个计数值。 然后线程尝试获取许可，如果计数为 0 或小于 0，则线程将被阻塞，并且它将等待下一个许可（如果有）。 这将一直保持下去，直到数量大于 0。如果是，则信号量将提供对线程资源的访问。 然后线程将释放许可，计数将增加 1。

## 构造器

1.  `Semaphore(int permits)`：使用给定数量的许可和不公平的公平设置创建一个信号量
2.  `Semaphore(int permits, boolean fair)`：创建具有给定许可数量和给定公平性设置的信号量

## 主要方法

1.  `void acquire()`：从当前信号量获取许可，阻塞直到可用，否则线程被中断。
2.  `void acquire(int permits)`：从当前信号量获取指定的许可数量，直到所有可用或线程中断为止一直阻塞。
3.  `int availablePermites()`：返回当前信号量中可用的当前许可数量

要查看所有方法，[请单击此处，您将被重定向到 Oracle 官方文档](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html)。

信号量可用于锁定对特定资源的访问。 每个线程都必须请求“权限”，因此需要在访问资源之前调用方法`acquire()`。 当线程不再需要资源时，它必须调用`release()`来释放锁。

```java
import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

	public static void main(String[] args) throws Exception {	
		Semaphore semExample = new Semaphore(1);
		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.release();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();

		System.out.println("Available permits: " + semExample.availablePermits());

		semExample.acquire();
		System.out.println("Available permits: " + semExample.availablePermits());
	}
}

```

**输出**

```java
Available permits: 1
Available permits: 2
Available permits: 1
Available permits: 0
```

从上面的示例中可以看到，当您调用`release()`时，您正在向`Semaphore`实例添加许可。 当您调用`acquire()`时，您正在删除`permit()`。 如果没有许可证，而您打电话给获取，它将等待直到许可证被释放，因此在上例中将永远不会执行最后一个打印语句。

如果您有 1 个许可，然后又有一个`acquire()`调用，紧接着是一个`release()`调用，则称为锁。

```java
import java.util.concurrent.Semaphore;

public class SemaphoreDemo {

    Semaphore thread = new Semaphore(1);

    public static void main(String args[]) {
        final SemaphoreDemo test = new SemaphoreDemo();
        new Thread(){
            @Override
            public void run(){
              test.mutualExclusion(); 
            }
        }.start();

        new Thread(){
            @Override
            public void run(){
              test.mutualExclusion(); 
            }
        }.start();

    }

    private void mutualExclusion() {
        try {
        	System.out.println(Thread.currentThread().getName() + " is waiting to acquire a permit.");
        	thread.acquire();
            System.out.println("Permit has been acquired to " + Thread.currentThread().getName());
            Thread.sleep(1000);

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        	System.out.println(Thread.currentThread().getName() + " is releasing the permit...");
            thread.release();
            System.out.println("Released.");
        }
    } 

}

```

**输出**

```java
Thread-0 is waiting to acquire a permit.
Permit has been acquired to Thread-0
Thread-1 is waiting to acquire a permit.
Thread-0 is releasing the permit...
Released.
Permit has been acquired to Thread-1
Thread-1 is releasing the permit...
Released.
```

从输出中可以看到，线程 0 允许了一个获取，线程 1 开始等待为其本身获取一个许可，但是它（线程 1）仅在线程 0 释放其许可时才获得它。