Semaphore (信号量)是用来控制同 时访问 特定 资 源的 线 程数量,它通 过协调 各个 线 程,以


保 证 合理的使用公共 资 源。



计数信号灯。从概念上讲,信号量维护一组许可。每个{@link#acquire}都会在必要时阻塞,直到有许可证可用,然后再获取它。每个{@link#release}都会添加一个许可证,可能会释放一个阻塞收单机构。但是,没有使用实际的许可证对象;{@code信号量}只保留可用数量的计数,并相应地进行操作。



应用场景:


Semaphore 可以用于做流量控制,特 别 是公用 资 源有限的 应 用 场 景,比如数据 库连 接。假



如有一个需求,要 读 取几万个文件的数据,因 为 都是 IO 密集型任 务 ,我 们 可以启 动 几十个 线 程



并 发 地 读 取,但是如果 读 到内存后, 还 需要存 储 到数据 库 中,而数据 库 的 连 接数只有 10 个, 这



时 我 们 必 须 控制只有 10 个 线 程同 时获 取数据 库连 接保存数据,否 则 会 报错 无法 获 取数据 库连



接。 这 个 时 候,就可以使用 Semaphore 来做流量控制



package com.netty.obj.demo5.d4;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * @PackageName:com.netty.obj.demo5.d4 Description
 * @author:
 * @date:2022/1/12
 */
public class SemaphoreTest {
    private static final int THREAD_COUNT = 30;
    private static ExecutorService threadPool =Executors.newFixedThreadPool(THREAD_COUNT);
    private static Semaphore s = new Semaphore(10);

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        s.acquire();
                        System.out.println("save data");
                        s.release();
                    } catch (InterruptedException e) {
                    }
                }
            });
        }
        threadPool.shutdown();
    }
}



在代 码 中, 虽 然有 30 个 线 程在 执 行,但是只允 许 10 个并 发执 行。 Semaphore 的构造方法



Semaphore ( int permits )接受一个整型的数字,表示可用的 许 可 证 数量。 Semaphore ( 10 )表示允



许 10 个 线 程 获 取 许 可 证 ,也就是最大并 发 数是 10 。 Semaphore 的用法也很 简单 ,首先 线 程使用



Semaphore 的 acquire() 方法 获 取一个 许 可 证 ,使用完之后 调 用 release() 方法 归还许 可 证 。 还 可以



用 tryAcquire() 方法 尝试获 取 许 可 证 。




Semaphore 还 提供一些其他方法,具体如下。



·intavailablePermits() :返回此信号量中当前可用的 许 可 证 数。



·intgetQueueLength() :返回正在等待 获 取 许 可 证 的 线 程数。



·booleanhasQueuedThreads() :是否有 线 程正在等待 获 取 许 可 证 。



·void reducePermits ( int reduction ):减少 reduction 个 许 可 证 ,是个 protected 方法。



·Collection getQueuedThreads() :返回所有等待 获 取 许 可 证 的 线 程集合,是个 protected 方



法。




总结:案例来源《Java并发编程的艺术》,主要熟悉Semaphore的业务应用场景,希望有帮助。