并发流程工具Semaphore的使用

一个计数信号量。 在概念上,信号量维持一组许可证。 如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它。 每个release()添加许可证,潜在地释放阻塞的线程。 记得以前校招,一个公司对应很多面试的学生,因为人数太多每次至多面试5个人,其他人只能等待,除非有人出来,等待的人才有机会进去,一般是排队公平进去,但是大家为了找工作都是抢着进去面试,大概是这么个意思。等待就是acquire(),有人出来就是release(),Semaphore底层使用AQS实现

案例分析

public class SemaphoreDemo {
    //添加3个许可证,采取公平策略,默认是分公平的
    static Semaphore semaphore = new Semaphore(3, true);

    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(50);
        for (int i = 0; i < 10; i++) {
            service.submit(new Task());
        }
        service.shutdown();
    }

    static class Task implements Runnable {

        @Override
        public void run() {
            try {
                //每个线程需要3个许可证才能进来,如果没有3个就阻塞,直到有满足的许可证可用
                semaphore.acquire(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "拿到了许可证");
//            try {
//                Thread.sleep(2000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            System.out.println(Thread.currentThread().getName() + "释放了许可证");
            //释放三个许可证
            semaphore.release(3);
        }
    }
}

在这里插入图片描述
如果 semaphore.acquire(3);改为 semaphore.acquire(4);那么所有线程都会阻塞,因为总共就只有三个许可证,或者 semaphore.release(3);改为 semaphore.release(2);那么第从二个线程开始所有线程都会阻塞,因为执行需要3个许可证,但是第一个执行的线程只释放了2个许可证

总之.release()操作happen-before acquire()操作,即释放操作在获取操作之前,释放对获取可见

此类共有两个构造方法,两个参数的构造可以选择公平策略,默认是非公平的。
.release()与acquire()默认参数是1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章