-
Semaphore(信号量)用于限制线程并发的数量(控制同时访问特定资源的线程数量),通过协调各个线程以保证合理地使用公共资源。
- Semaphore通过使用计数器来控制对共享资源的访问。 如果计数器
大于0
,则允许访问。 如果为0,则拒绝访问。 计数器所计数的是允许访问共享资源的许可。 因此,要访问资源,必须从信号量中授予线程许可。 -
主要方法
void acquire() :从信号量获取一个许可,如果无可用许可前将一直阻塞等待,获取到后减1void acquire(int permits) :获取指定数目的许可,如果无可用许可前也将会一直阻塞等待
boolean tryAcquire():从信号量尝试获取一个许可,如果无可用许可,直接返回false,不会阻塞
boolean tryAcquire(int permits): 尝试获取指定数目的许可,如果无可用许可直接返回false
boolean tryAcquire(int permits, long timeout, TimeUnit unit):
在指定的时间内尝试从信号量中获取许可,如果在指定的时间内获取成功,返回true,否则返回falsevoid release():释放一个许可,别忘了在finally中使用,注意:多次调用该方法,会使信号量的许可数增加,达到动态扩展的效果,如:初始permits为1,调用了两次release,最大许可会改变为2
int availablePermits(): 获取当前信号量可用的许可
-
public class ThreadSemaphore { public static void main(String[] args) { //可以指定最多支持多个资源访问的数量 Semaphore semaphore = new Semaphore( 5); ExecutorService executorService = Executors.newFixedThreadPool(10); //线程池模拟登录 for (int i = 1; i <= 10 ; i++) { int j = i; executorService.execute(new Runnable() { @Override public void run() { if(semaphore.tryAcquire()){//从信号量获取一个许可,如果无可用许可,直接返回false,不会阻塞 System.out.println("用户"+ j + "登录成功"); }else{ System.out.println("用户"+ j + "登录失败"); } } }); } executorService.shutdown(); System.out.println("当前可用许可证数:"+semaphore.availablePermits());// 获取当前信号量可用的许可 //此时已经登录了10个用户,再次登录的时候会返回false if (semaphore.tryAcquire()){ System.out.println("登录成功!"); }else{ System.out.println("登录失败,当前系统登录用户已满,请稍后再来!"); } //释放一个许可 semaphore.release(); System.out.println("一个用户下线了!"); //再次登录 if (semaphore.tryAcquire()){ System.out.println("登录成功!"); }else{ System.out.println("系统登录用户已满,登录失败!"); } } }
结果:
java多线程之Semaphore
最新推荐文章于 2023-01-17 17:17:42 发布