Java Semaphore类详解说明

打印 上一主题 下一主题

主题 867|帖子 867|积分 2601

转自:
http://www.java265.com/JavaCourse/202204/3184.html
下文笔者讲述java中Semaphore类的详解说明,如下所示:
Semaphore简介
  1. Semaphore(中文翻译:信号量)
  2.    我们常用于控制访问某一资源的线程个数,
  3.    使用这种方式可使大家按照一定的规则访问某一资源
  4. Semaphore的原理:
  5.      通过使用计数器来控制对某一资源的访问
  6.           当计数器大于0,则允许访问
  7.       当计数器为0时,则拒绝访问
  8.       计数器中的计数作为允许访问共享资源的许可
  9. 即:访问资源,需从信号量中授予线程许可
复制代码
Semaphore方法

方法名备注
void acquire()从信号量获取一个许可,在无可用许可前,将一直阻塞等待
void acquire(int permits)获取指定数目的许可,在无可用许可前,也将会一直阻塞等待
boolean tryAcquire()从信号量尝试获取一个许可,当无可用许可,直接返回false,不会阻塞
boolean tryAcquire(int permits)尝试获取指定数目的许可,当无可用许可直接返回false
boolean tryAcquire(int permits, long timeout, TimeUnit unit)在指定的时间内尝试从信号量中获取许可,当在指定的时间内获取成功,返回true,否则返回false
void release()释放一个许可,别忘了在finally中使用
注意:多次调用该方法,会使信号量的许可数增加,达到动态扩展的效果
如:初始permits为1,调用了两次release,最大许可会改变为2
int availablePermits()获取当前信号量可用的许可
Semaphore构造函数
  1. public Semaphore(int permits) {
  2.         sync = new NonfairSync(permits);
  3.     }
  4. public Semaphore(int permits, boolean fair) {
  5.         sync = fair ? new FairSync(permits) : new NonfairSync(permits);
  6.     }
  7. 参数说明:
  8.      permits:初始许可数,即最大访问线程数
  9.      fair:当设置为false时,创建的信号量为非公平锁;当设置为true时,信号量是公平锁
复制代码
使用Semaphore限制登录的最大用户数
  1. package com.java265.other;
  2. import java.util.concurrent.ExecutorService;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.Semaphore;
  5. public class Test16 {
  6.         public static void main(String[] args) {
  7.                 // 允许最大的获取用户的线程数
  8.                 int slots = 8;
  9.                 ExecutorService executorService = Executors.newFixedThreadPool(slots);
  10.                 UserUsingSemaphore loginQueue = new UserUsingSemaphore(slots);
  11.                 // 线程池模拟登录
  12.                 for (int i = 1; i <= slots; i++) {
  13.                         final int num = i;
  14.                         executorService.execute(() -> {
  15.                                 if (loginQueue.tryAcquire()) {
  16.                                         System.out.println("用户:" + num + "获取成功!");
  17.                                 } else {
  18.                                         System.out.println("用户:" + num + "获取失败!");
  19.                                 }
  20.                         });
  21.                 }
  22.                 executorService.shutdown();
  23.                 System.out.println("当前可用许可证数:" + loginQueue.availableSlots());
  24.                 // 此时已经有8个线程,再次获取的时候会返回false
  25.                 if (loginQueue.tryAcquire()) {
  26.                         System.out.println("获取成功!");
  27.                 } else {
  28.                         System.out.println("资源已经被占满,获取失败!");
  29.                 }
  30.                 // 有用户释放资源,只释放一个资源
  31.                 loginQueue.releaseAcquire();
  32.                 // 再次获取
  33.                 if (loginQueue.tryAcquire()) {
  34.                         System.out.println("获取成功-2!");
  35.                 } else {
  36.                         System.out.println("资源已经被占满,获取失败-2!");
  37.                 }
  38.                 // 再次获取-会失败,因为又没有空余
  39.                 if (loginQueue.tryAcquire()) {
  40.                         System.out.println("获取成功-3!");
  41.                 } else {
  42.                         System.out.println("资源已经被占满,获取失败-3!");
  43.                 }
  44.         }
  45. }
  46. /*
  47. * 定义一个登录队列,用于获取信号量
  48. */
  49. class UserUsingSemaphore {
  50.         private Semaphore semaphore;
  51.         /**
  52.          * @param 设置信号量的大小
  53.          */
  54.         public UserUsingSemaphore(int slotLimit) {
  55.                 semaphore = new Semaphore(slotLimit);
  56.         }
  57.         boolean tryAcquire() {
  58.                 // 获取一个凭证
  59.                 return semaphore.tryAcquire();
  60.         }
  61.         /*
  62.          * 释放凭证
  63.          */
  64.         void releaseAcquire() {
  65.                 semaphore.release();
  66.         }
  67.         /*
  68.          * 获取可用的凭证数量
  69.          */
  70.         int availableSlots() {
  71.                 return semaphore.availablePermits();
  72.         }
  73. }
  74. ------运行以上代码,将输出以下信息------
  75. 用户:1获取成功!
  76. 用户:5获取成功!
  77. 用户:2获取成功!
  78. 用户:4获取成功!
  79. 用户:3获取成功!
  80. 用户:7获取成功!
  81. 用户:6获取成功!
  82. 当前可用许可证数:1
  83. 资源已经被占满,获取失败!
  84. 获取成功-2!
  85. 资源已经被占满,获取失败-3!
  86. 用户:8获取成功!
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表