semaphore简介

以前写过关于线程同步辅助类: CountDownLatch和CyclicBarrier,本次介绍写另一个线程同步辅助类:Semaphore。

简介

信号量(semaphore)是在多线程环境下负责协调各个线程,正确合理的使用公用资源。Semaphore是基于计数的信号量。它可以设定一个阈值,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制。

API

创建信号量

Semaphore(int permits)

参数permits(许可)指定了同时可以多少个线程访问公共资源。

若设置1,则可用于线程间同步
若设置>1,则可用于限流等

阻塞获取信号量

acquire()

释放信号量

release()

使用场景

常用于仅能提供有限访问的资源,如数据库链接数最大只有20, 而上层应用并发数远大于20,如果同时对数据库进行操作,则就会出现因无法获取数据库连接数而导致的异常。此时就可以通过该信号量来做并发访问限制。

实际案例

 @org.junit.Test
    public void test() throws InterruptedException {

        AtomicInteger index = new AtomicInteger();
        //执行线程池
        Executor executor = Executors.newFixedThreadPool(10);
        //初始化信号量
        Semaphore semaphore = new Semaphore(4);
        //任务执行完成信号
        CountDownLatch countDownLatch = new CountDownLatch(10);
        //执行任务
        for (int i = 0; i < 10; i++) {
            executor.execute(new Task(semaphore, countDownLatch));
        }
        countDownLatch.await();
        System.out.println(simpleDateFormat.format(new Date())+"==============全部执行完成!");
    }

    private class Task implements  Runnable{

        private Semaphore semaphore;
        private CountDownLatch countDownLatch;

        Task(Semaphore semaphore, CountDownLatch countDownLatch){
            this.semaphore = semaphore;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public void run() {
            try {
                //获取许可
                semaphore.acquire();
                System.out.println(simpleDateFormat.format(new Date())+" "+Thread.currentThread().getName() + ": 执行中");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            } finally {
                //释放许可
                semaphore.release();
                //任务执行标示
                countDownLatch.countDown();
            }

        }
    }

你可能感兴趣的:(多线程,多线程)