• 并发控制-信号量(Semaphore)


    信号量用来控制有限资源的方法,举例:假如信号量为3,则同时只有3个线程共享。

    概述

      信号量用来控制系统耗时资源的访问,一般我们初始设置了一个公平的信号量,线程在使用时需要申请,用完之后需要释放。

    使用流程

      信号量Semaphore的使用流程如下:

      一般设置公平的信号量-->线程在使用时需要进行require申请-->若可以申请到,则执行自己的逻辑-->执行完成后,需要释放信号量

      -->若未申请到,则可以阻塞,直到申请到。

    主要方法

      信号量的部分常用方法如下:

      1.信号量构造:public Semaphore(int permits, boolean fair) 

      2.获取信号量:public void acquire();acquireUninterruptibly();tryAcquire() ;tryAcquire(long timeout, TimeUnit unit)

      3.释放信号量:release();release(int permits)

    实例代码

      下面我们通过初始化一个3容量的信号量,我们用100个线程去获取这个信号量,每次申请一个信号量,当用完之后,我们释放这一个,如以下实例代码所示:

      

    package com.yang.concurrent;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.stream.IntStream;
    
    public class SemaphoreDemp {
        static Semaphore   semaphore  =new Semaphore(3,true);
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            for (int i = 0; i < 100; i++) {
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            System.out.println(Thread.currentThread().getName()+"等待获取信号量");
                            semaphore.acquire();
                            System.out.println(Thread.currentThread().getName()+"取到了信号量");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }finally {
                            System.out.println(Thread.currentThread().getName()+"释放信号量");
                            semaphore.release();
                        }
                    }
                };
                executorService.submit(runnable);
            }
            executorService.shutdown();
        }
    }
    

      运行结果如下图所示:

      

    特殊用法及注意点

      1.申请和释放的信号量必须保持一致,在信号量申请时,比如我们可以申请2个,释放的时候也可以释放2个,这个场景是指程序在运行时,可能需要多个资源

      2.信号量在初始化的时候,可以设置为公平或者非公平,我们一般设置为公平,对耗时长的资源访问时,一般不允许争夺

      3.信号量在获取和释放时,对是否是同一个线程没有限制。

  • 相关阅读:
    【贪心】闭区间问题
    【贪心】电视节目安排
    中石油-高精度阶乘-java
    hdu 6444 Neko's loop 单调队列优化DP
    hdu 3415 Max Sum of Max-K-sub-sequence 单调队列优化DP
    51nod 1050 循环数组最大子段和 单调队列优化DP
    hdu 6406 Taotao Picks Apples 线段树 单点更新
    Wannafly 挑战赛22 D 整数序列 线段树 区间更新,区间查询
    dp专题训练
    zoj 3747 递推dp
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12774532.html
Copyright © 2020-2023  润新知