控制并发线程数-Semaphore(信号量)的简单使用

Semaphore(信号量)用来控制并发访问的线程数量,它通过协调各个线程来保证资源的合理使用。其内部使用的是AQS机制(concurrent包下很多类实现原理都是基于AQS)。Semaphore实现控制并发线程数可以抽象为停车场模型,一个固定车位的停车场,当车位满了,便不再允许新的车辆进入;若当前车库驶出多少辆,则就允许进入多少辆。Semaphore做的就是监控车位大小功能。通过构造函数new Semaphore(N)来实现,N表示最多并发访问的线程数,显然,当N=1时候,就相当于 synchronized或Lock实现的同步操作(并发数为1)。所以当初始化创建了5个信号量时,如果多余5个线程并发访问则阻塞排队等候,至于是否公平访问,可以灵活的设置new Semaphore(int permits,boolean fair),当前线程tryAcquire()一次信号量就减少一个,release()一次就归还一个,以此来保证了同一时刻的并发线程数。

Semaphore应用场景

例如IO密集型操作,开启了30个工作线程并发的读取文件,然后进行持久化操作,但是数据库最大连接数为20,如果不控制,就出现获取数据库连接失败错误,通过Semaphore控制并发连接数据库线程数

public class SemaphoreTest {
    static ExecutorService executor = Executors.newFixedThreadPool(30);
    static Semaphore semaphore = new Semaphore(20, true);

    public static void main(String[] args) {
        for (int i = 0; i < 30; i++) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    semaphore.tryAcquire();  //获取许可证
                    // TODO something  work
                    System.out.println("current thread " + Thread.currentThread().getId() + " time=" + System.currentTimeMillis());
                    semaphore.release();  //归还许可证
                }
            });
        }
        executor.shutdown();
    }
}

上述代码所示,进行时的工作线程数有30个,但是允许并发执行的只有20个,通过new Semaphore(20,true)设置即可,使用semaphore.tryAcquire()来获取许可证,操作完后semaphore.release()方法来归还许可证,使用还是比较简单的。

你可能感兴趣的:(Java,Java编程之路)