Semaphore的作用:限制线程并发的数量

 

位于 java.util.concurrent 下,

 

构造方法

    // 构造函数  代表同一时间,最多允许permits执行acquire() 和release() 之间的代码。
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }

    //False:表示非公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序无关,也就是线程先启动了并不代表先获得 许可
   //True:公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序有关,也就是先启动的线程优先获得许可
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

 

并发编程Semaphore详解

 

 

 

  1. 方法acquire(n) 的功能是每调用1次此方法,就消耗掉n个许可。
  2. 方法release(n) 的功能是每调用1次此方法,就动态添加n个许可。
  3. 方法acquireUnnterruptibly()作用是是等待进入acquire() 方法的线程不允许被中断。
  4. 方法availablePermits() 返回Semaphore对象中当前可以用的许可数。
  5. 方法drainPermits() 获取并返回所有的许可个数,并且将可用的许可重置为0
  6. 方法 getQueueLength() 的作用是取得等待的许可的线程个数
  7. 方法 hasQueueThreads() 的作用是判断有没有线程在等待这个许可
  8. 方法tryAcquire() 的作用是尝试获取1个许可。如果获取不到则返回false,通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可以使不至于在同步处于一直持续等待的状态。
  9. 方法tryAcquire(n) 的作用是尝试获取n个许可,如果获取不到则返回false
  10. 方法tryAcquire(long timeout,TimeUnit unit)的作用是在指定的时间内尝试获取1个许可,如果获取不到则返回false
  11. 方法tryAcquire(int permits,long timeout,TimeUnit unit) 的作用是在指定的时间内尝试获取n 个许可,如果获取不到则返回false

 

使用:

多进路-多处理-多出路:允许多个线程同时处理任务

    private static Semaphore semaphore = new Semaphore(4);

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable(){
                @Override
                public void run(){
                    System.out.println(Thread.currentThread().getName()+"  正在运行");
                    try {
                        semaphore.acquire();// //请求获得许可,如果有可获得的许可则继续往下执行,许可数减1。否则进入阻塞状态
                        System.out.println(Thread.currentThread().getName() + "进入,并发数:" + (4-semaphore.availablePermits()));
                        Thread.sleep(3000);
                        System.out.println(Thread.currentThread().getName() +"即将离开,并发数:" + (4-semaphore.availablePermits()));
                        semaphore.release();//释放许可,许可数加1
                    }catch( Exception e){
                        e.printStackTrace();
                    } finally {
                    }
                }
            }).start();
        }
    }

 

运行结果:

Thread-1  正在运行
Thread-6  正在运行
Thread-7  正在运行
Thread-5  正在运行
Thread-3  正在运行
Thread-2  正在运行
Thread-4  正在运行
Thread-0  正在运行
Thread-5进入,并发数:4
Thread-9  正在运行
Thread-7进入,并发数:3
Thread-8  正在运行
Thread-6进入,并发数:2
Thread-1进入,并发数:1
Thread-7即将离开,并发数:4
Thread-5即将离开,并发数:4
Thread-1即将离开,并发数:4
Thread-2进入,并发数:4
Thread-6即将离开,并发数:4
Thread-4进入,并发数:4
Thread-0进入,并发数:4
Thread-3进入,并发数:3
Thread-3即将离开,并发数:4
Thread-4即将离开,并发数:4
Thread-0即将离开,并发数:4
Thread-2即将离开,并发数:4
Thread-8进入,并发数:4
Thread-9进入,并发数:4
Thread-8即将离开,并发数:2
Thread-9即将离开,并发数:2

当使用:公平锁时:  private static Semaphore semaphore = new Semaphore(num,true);

仔细看结果,就会发现先运行的线程会优先处理

Thread-1  正在运行
Thread-5  正在运行
Thread-5进入,并发数:2
Thread-4  正在运行
Thread-4进入,并发数:3
Thread-2  正在运行
Thread-2进入,并发数:4
Thread-3  正在运行
Thread-0  正在运行
Thread-9  正在运行
Thread-8  正在运行
Thread-7  正在运行
Thread-6  正在运行
Thread-1进入,并发数:1
Thread-4即将离开,并发数:4
Thread-5即将离开,并发数:4
Thread-3进入,并发数:4
Thread-2即将离开,并发数:4
Thread-0进入,并发数:4
Thread-9进入,并发数:4
Thread-1即将离开,并发数:3
Thread-8进入,并发数:4
Thread-3即将离开,并发数:4
Thread-7进入,并发数:4
Thread-9即将离开,并发数:4
Thread-8即将离开,并发数:4
Thread-0即将离开,并发数:4
Thread-6进入,并发数:4
Thread-7即将离开,并发数:2
Thread-6即将离开,并发数:1
View Code

相关文章:

  • 2022-12-23
  • 2022-02-03
  • 2022-01-18
  • 2021-11-15
  • 2021-11-15
  • 2021-06-30
  • 2021-06-11
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-23
  • 2022-01-23
  • 2022-02-14
  • 2022-12-23
  • 2021-06-06
相关资源
相似解决方案