Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:

  • availablePermits() //用来获取当前可用的资源数量
  • wc.acquire(); //申请资源
  • wc.release();// 释放资源
import java.util.Random;
import java.util.concurrent.Semaphore; public class SemaphoreDemo implements Runnable{
private String name;
private Semaphore semaphore; public SemaphoreDemo(String name, Semaphore semaphore) {
this.name = name;
this.semaphore = semaphore;
} @Override
public void run() {
try {
//剩余的资源
int i = semaphore.availablePermits();
if (i > 0){
System.out.println(name+" 有资源了");
}else {
System.out.println(name+" 没资源了");
}
semaphore.acquire();
System.out.println(name+"资源到手");
Thread.sleep(new Random().nextInt(1000));
System.out.println(name+"好!!!");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 5; i++) {
SemaphoreDemo demo = new SemaphoreDemo("第"+i+"个",semaphore);
new Thread(demo).start();
}
}
//第1个 有资源了
//第1个资源到手
//第2个 有资源了
//第2个资源到手
//第3个 有资源了
//第3个资源到手
//第4个 没资源了
//第5个 没资源了
//第2个好!!!
//第4个资源到手
//第1个好!!!
//第5个资源到手
//第3个好!!!
//第4个好!!!
//第5个好!!!
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; /**
* 信号量:允许多个线程同时访问
* public Semaphore(int permits)
* public Semaphore(int permits,boolean fair) //第二参数可以指定是否公平
*/
public class SemapDemo implements Runnable{
final Semaphore semaphore = new Semaphore(5);//指定信号量的准入数
@Override
public void run() {
try {
semaphore.acquire();//尝试获取一个准入的许可,若无法获得,则线程会等待,直到有线程释放一个许可或当前线程被中断
Thread.sleep(2000);
System.out.println(Thread.currentThread().getId()+":done");
semaphore.release();//线程访问资源结束后,释放一个许可
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args){
//线程池
ExecutorService exec = Executors.newFixedThreadPool(20);
final SemapDemo demo = new SemapDemo();
for (int i = 0; i < 20; i++) {
exec.submit(demo);
}
}
//同时开启20个线程,系统以5个线程一组为单位,依次输出带有线程ID的提示文本
}

最新文章

  1. 如何安装appium-linux
  2. Python标准库13 循环器 (itertools)
  3. EasyUI实现工地领款单项目
  4. 与你相遇好幸运,aglio写接口文档
  5. 总结-computer
  6. 三、jQuery--jQuery基础--jQuery基础课程--第8章 jQuery 实现Ajax应用
  7. 决策树ID3算法示例
  8. 454. 4Sum II ——查找本质:hash最快,二分次之
  9. Educational Codeforces Round 7 B. The Time 水题
  10. C++实现设计模式之 — 简单工厂模式
  11. thinkphp 统计某个字段不重复数 总数
  12. frame模型
  13. [Linked List]Remove Duplicates from Sorted List II
  14. 修改XPMenu让ToolButton在Down=True时正确显示
  15. 【Python】Part I 设置Python环境
  16. Redis 集群环境的搭建
  17. dotnet new 命令使用模板生成Angular应用
  18. js-jquery-Validate校验【一】
  19. Metasploit漏洞利用,三个入侵主机实战案例
  20. HDUOJ------(1272)小希的迷宫

热门文章

  1. 前端每日实战:53# 视频演示如何用纯 CSS 创作一个文本淡入淡出的 loader 动画
  2. 《嵌入式软件设计基础——基于ARM Cortex—M3》读书笔记
  3. 环境变量,env, set
  4. C#高级编程笔记(22至25章节)文件\注册表\权限\事务
  5. 【leetcode】1014. Capacity To Ship Packages Within D Days
  6. 禁止打开 F12 开发者工具
  7. 多线程模拟生产者消费者示例之wait/notify
  8. JDBC调用oracle 存储过程
  9. JS中数据结构之图
  10. windows防火墙批量开放端口