原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11872132.html

Java线程--Semaphore使用

Semaphore是信号量, 也叫许可证管理器, 类似于取票窗口, 办事窗口, 打饭窗口等等这种情况, 只有排队等到了这样才算拿到了信号量, 拿到了许可证 .

package concurrent.semaphore;

import java.util.concurrent.Semaphore;

/**
* 信号量 , 许可证管理器 main 测试类
*/
public class MainTest { public static void main(String[] args) throws InterruptedException {
/**
* 定义2个取票窗口, 公平的排队取票
*/
Semaphore ticketWindow = new Semaphore(2, true);
Thread[] threads = new Thread[10];
for (int i = 0 ; i < 30; i++) {
/**
* 前面十个小伙伴坚持排队
*/
if (i < 10) {
new Thread(new Man("坐火车良民" + i, ticketWindow, 0)).start();
} else if (i >= 10 && i < 20) {
/**
* 这5个小伙伴没有耐心,只会等1毫秒
*/
new Thread(new Man("坐飞机良民" + i, ticketWindow, 1)).start();
} else {
/**
* 这5个小伙伴没有耐心
*/
threads[i - 20] = new Thread(new Man("回家吃饭良民" + i, ticketWindow, 2));
threads[i - 20].start();
}
} Thread.sleep(2000);
for (int i = 0; i < 5; i++) {
threads[i].interrupt();
}
} void show(){
/**
* 初始化许可证数量, 5个许可证/信号量, 公平模式
*/
Semaphore semaphore = new Semaphore(5, true);
try {
/**
* 获取一个许可证/信号量
* 此线程会一直阻塞,直到获取这个许可证,或者被中断(抛出InterruptedException异常)
*/
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 释放一个许可证/信号量
*/
semaphore.release();
try {
/**
* 获取3个许可证/信号量
* 此线程会一直阻塞,直到获取这个许可证,或者被中断(抛出InterruptedException异常)
*/
semaphore.acquire(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 释放3个许可证/信号量
*/
semaphore.release(3);
/**
* 是否有正在等待许可证的线程
*/
semaphore.hasQueuedThreads();
/**
* 正在等待许可证的队列长度(线程数量)
*/
semaphore.getQueueLength();
/**
* 剩余许可证的数量
*/
semaphore.drainPermits();
/**
* 尝试获取, 获取不到就返回false
*/
semaphore.tryAcquire();
/**
* 获取的时候无法被打断
*/
semaphore.acquireUninterruptibly();
}
}
package concurrent.semaphore;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; /**
* 排队取票的人
*/
public class Man implements Runnable { /**
* 取票的人的姓名
*/
private String name;
/**
* 必须要的取票证明
*/
private Semaphore semaphore;
/**
* 最后的行为
* 0 : 取到票为止
* 1 : 排队的时候不耐烦, 走了, 买飞机票去了
* 2 : 排队的时候突然有事, 回家去了
*/
private int behav; public Man(String name, Semaphore semaphore, int behav) {
this.name = name;
this.semaphore = semaphore;
this.behav = behav;
} @Override
public void run() {
switch (behav) {
/**
* 坚持到底
*/
case 0 :
/**
* 排队, 坚持不懈 , 就是要拿到许可证
*/
semaphore.acquireUninterruptibly();
try {
Thread.sleep(1000);
System.out.println("我正在取票啦!! " + name);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
System.out.println("哇, 我终于取到票啦!! " + name);
break;
/**
* 买不到我就坐飞机
*/
case 1 :
try {
if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
System.out.println("我正在取票啦!! " + name);
Thread.sleep(2000);
semaphore.release();
System.out.println("哇, 我终于取到票啦!! " + name);
} else {
System.out.println("我不取了, 坐飞机去啦!! " + name);
}
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 买不到我就回家
*/
case 2 :
try {
semaphore.acquire();
try {
Thread.sleep(1000);
System.out.println("我正在取票啦!! " + name);
} catch (InterruptedException e) {
e.printStackTrace();
}
semaphore.release();
System.out.println("哇, 我终于取到票啦!! " + name);
} catch (InterruptedException e) {
//e.printStackTrace();
System.out.println("算了, 回家吃饭去了 " + name);
}
break;
/**
* 不知道这个人是干嘛的, 黄牛吧
*/
default:
break;
}
}
}

打印如下:

我正在取票啦!!  坐火车良民0
我正在取票啦!! 坐火车良民1
哇, 我终于取到票啦!! 坐火车良民0
哇, 我终于取到票啦!! 坐火车良民1
我不取了, 坐飞机去啦!! 坐飞机良民10
我不取了, 坐飞机去啦!! 坐飞机良民17
我不取了, 坐飞机去啦!! 坐飞机良民19
我不取了, 坐飞机去啦!! 坐飞机良民16
我不取了, 坐飞机去啦!! 坐飞机良民13
我不取了, 坐飞机去啦!! 坐飞机良民15
我不取了, 坐飞机去啦!! 坐飞机良民14
我不取了, 坐飞机去啦!! 坐飞机良民12
我不取了, 坐飞机去啦!! 坐飞机良民11
我不取了, 坐飞机去啦!! 坐飞机良民18
我正在取票啦!! 坐火车良民3
哇, 我终于取到票啦!! 坐火车良民3
我正在取票啦!! 坐火车良民2
哇, 我终于取到票啦!! 坐火车良民2
算了, 回家吃饭去了 回家吃饭良民20
算了, 回家吃饭去了 回家吃饭良民23
算了, 回家吃饭去了 回家吃饭良民22
算了, 回家吃饭去了 回家吃饭良民24
算了, 回家吃饭去了 回家吃饭良民21
我正在取票啦!! 坐火车良民4
哇, 我终于取到票啦!! 坐火车良民4
我正在取票啦!! 坐火车良民5
哇, 我终于取到票啦!! 坐火车良民5
我正在取票啦!! 坐火车良民6
哇, 我终于取到票啦!! 坐火车良民6
我正在取票啦!! 坐火车良民7
哇, 我终于取到票啦!! 坐火车良民7
我正在取票啦!! 坐火车良民8
哇, 我终于取到票啦!! 坐火车良民8
我正在取票啦!! 坐火车良民9
哇, 我终于取到票啦!! 坐火车良民9
我正在取票啦!! 回家吃饭良民25
哇, 我终于取到票啦!! 回家吃饭良民25
我正在取票啦!! 回家吃饭良民26
哇, 我终于取到票啦!! 回家吃饭良民26
我正在取票啦!! 回家吃饭良民29
哇, 我终于取到票啦!! 回家吃饭良民29
我正在取票啦!! 回家吃饭良民27
哇, 我终于取到票啦!! 回家吃饭良民27
我正在取票啦!! 回家吃饭良民28
哇, 我终于取到票啦!! 回家吃饭良民28

Java线程--Semaphore使用的更多相关文章

  1. Java线程并发:知识点

    Java线程并发:知识点   发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用.   逃逸:在对象尚未准备 ...

  2. 【转载】 Java线程面试题 Top 50

    Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...

  3. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  4. Java线程:概念与原理

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

  5. Java线程面试题 Top 50 (转载)

    转载自:http://www.cnblogs.com/dolphin0520/p/3958019.html 原文链接:http://www.importnew.com/12773.html   本文由 ...

  6. java线程详解

    Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程 ...

  7. 50 道 Java 线程面试题(转载自牛客网)

    下面是 Java 线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理 ...

  8. Java线程面试题 Top 50

    转自:http://www.importnew.com/12773.html 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java ...

  9. 【多线程】Java线程面试题 Top 50(转载)

    Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html   本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎 ...

随机推荐

  1. 【HTML响应式项目】成人教育官网前端页面(HTML+CSS+JS实现三端适应)

    这个页面是在校参赛的小组项目,除首页和所有课程页面以外由组内成员编写,发博客纯属记录. 项目源码已上传至码云仓库:https://gitee.com/ynavc/sss 项目演示地址:http://y ...

  2. 计算机网络-4-11-IP多播

    IP多播 IP多播的基本概念 与单播相比,在一对多的通信中,多播可以大大减少网络资源.在互联网上进行多播就叫做IP多播,IP多播所传送的分组需要使用多播IP地址.能够运行多播协议的路由器叫做多播路由器 ...

  3. android 解决报错 installation failed with message Failed to finalize session : INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Failed parse during installPackageLI: Failed to read manifest from /xx/xx/xx.apk

    新工程启动报错 怎么办? 解决: 将这个选项去掉勾选后点击ok即可

  4. PowerShell【Do While、Do Until篇】

    1 $num=0 2 while($num -le 10) 3 { 4 $num 5 $num+=1 6 } 1 $num=0 2 do 3 { 4 $num 5 $num+=1 6 } 7 whil ...

  5. Node.js 模块之【passport】

    什么是passport passport是Nodejs的一个中间键,用于用户名和密码的验证登陆.在项目中我用它来验证后台用户名和密码,但passport更多用在第三方登录,功能强大. 安装与配置 本项 ...

  6. Nginx日志通过Flume导入到HDFS中

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新) flume上传到hdfs: 当我们的数据量比较大时,比如每天的日志文件达到5G以上 使用ha ...

  7. 利用Spring AOP切面对用户访问进行监控

    开发系统时往往需要考虑记录用户访问系统查询了那些数据.进行了什么操作,尤其是访问重要的数据和执行重要的操作的时候将数记录下来尤显的有意义.有了这些用户行为数据,事后可以以用户为条件对用户在系统的访问和 ...

  8. Mysql group by之 Error 1055

    统计每个班级有多少人 我按照班级名称进行分组,返回  班级id和班级name出现了如下错误 报错的查询语句如下 -- 统计每个班级有多少人select c.id,c.name,count(*) fro ...

  9. leetcode 51. N皇后 及 52.N皇后 II

    51. N皇后 问题描述 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后 ...

  10. 【经验总结-markdown】markdown字体和颜色设置

    字体设置 关键词为face <font face = "黑体">我是黑体</font> <font face = "宋体"> ...