java并发工具类之Semaphore

一.介绍

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。通俗的理解就是,Semaphore能够控制并发线程的数量,可以把它比作控制流量的红绿灯,比如说马路要限制流量,只允许同时一百辆汽车在这条路上行驶,其他的都必须在路口等待,所以前一百辆车会看到绿灯,可以开进这条马路,而后面的车则会看到红灯,不能驶入马路,但是如果前一百辆车中有5辆已经驶出马路,那么就允许有5辆车驶入,这里的车则就是线程,驶入线程表示线程执行,离开马路则表示线程执行完成,看见红灯表示线程被堵塞,不能执行。

二.使用

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

场景:比如说我们有一个需求,要读取几万个文件的数据,因为都是IO密集型的任务,我们可以使用多线程并发读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数是有限制的,限制是10,这时候我们就必须控制只有10个线程同时获取数据库的连接来保存,否则就会报错无法获取数据库连接。


public class SemaphoreTest {


    // 线程数量
    private static  final  int  THREAD_NUM= 50;
    private static Executor  threadPool= Executors.newFixedThreadPool(THREAD_NUM);
    private static Semaphore semaphore = new Semaphore(10);


    public static void main(String[] args) {

        // 投寄任务
        for (int i=0 ; i<THREAD_NUM  ; ++i){

            threadPool.execute(()->{
                try {
                    semaphore.acquire(); // 获取许可证
                    System.out.println("save ....");
                    semaphore.release(); // 释放许可证
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

这里首先有50个任务投寄给线程池执行,但是只有10个线程能够同时并发执行。

Semaphore 构造方法接受一个整数值,表示可用的许可证数量,Semaphore(10)表示允许10个线程获取许可证。

acquire()方法获取一个许可证。

release()方法是释放一个许可证。如果一直不释放,其他线程只好一直在等着了,就跟一个萝卜一个坑一样,比如我们要是把上面代码中的释放许可证那一块注释掉,这时候在运行,只会打印10次了,然后就hang在那了。

tryAcquire()尝试获取许可证,返回一个boolean值,是否获取成功。

availablePermits() 返回信号量中当前可用的许可证数。

getQueueLength()返回信号量中正在等待获取许可证的线程数。

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

getQueuedThreads()返回所有等待获许可证的线程集合,是一个protected方法。

reducePermits(int reducetion) 减少reducetion个许可证,是个protected方法。

猜你喜欢

转载自blog.csdn.net/yuanshangshenghuo/article/details/99113192
今日推荐