Semphore 典型用法

593 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

Semphore意为信号量,可以发放一定数量的授权,只有拿到授权的线程才能继续工作,一般用于限流的场景,因此起构造器第二个参数一般为了避免任务堆积会设置为true

概述

Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目。

方法

构造方法

Semaphore(int)、Semaphore(int,boolean)

int表示该信号量拥有的许可数量

boolean表示获取许可的时候是否是公平的。(公平指的是先来的先执行)

获取许可

acquire()、acquire(int)、tryAcquire()

int参数表示一次性要获取几个许可,默认为1个,acquire方法在没有许可的情况下,要获取许可的线程会阻塞。

tryAcquire()方法在没有许可的情况下会立即返回 false,要获取许可的线程不会阻塞。

释放许可

release()、release(int)

int参数表示一次性要释放几个许可,默认为1个,

注意:一个线程调用release()之前并不要求一定要调用了acquire因此如果释放的比获取的信号量还多,例如获取了2个,释放了5次,那么当前信号量就动态的增加为5了(实现动态增加)

当前可用的许可数

int availablePermits()

代码演示

 package org.example.concurrent;
 ​
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;
 ​
 /**
  * Semaphore 用法演示
  * Semaphore 常用于限流场景
  * @author Catch
  */
 public class SemaphoreUsage {
 ​
     public static void main(String[] args) {
         Semaphore semaphore = new Semaphore(3,true);
         ExecutorService executorService = Executors.newFixedThreadPool(50);
         for (int i = 0; i < 100; i++) {
             int no=i+1;
             Runnable r=()->{
                 try {
                     semaphore.acquire();
                     System.out.println("No."+no+"拿到了授权");
                     Thread.sleep(2000);
                     System.out.println("No."+no+"释放了授权");
                     semaphore.release();
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
             };
             executorService.submit(r);
         }
         executorService.shutdown();
     }
 }

\