原创:转载需注明原创地址 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网页设计基础笔记 • 【第7章 盒子模型】

    全部章节   >>>> 本章目录 7.1 盒子模型原理 7.1.1 盒子模型概述 7.1.2 盒子的大小 7.1.3 盒子之间的关系 7.2 标准文档流 7.2.1 标准文档流 ...

  2. 编写Java程序,读取文本文档的内容,去除文本中包含的“广告”字样,把更改后的内容保存到一个新的文本文档中

    查看本章节 查看作业目录 需求说明: 读取文本文档的内容,去除文本中包含的"广告"字样,把更改后的内容保存到一个新的文本文档中 实现思路: 在main() 方法中,使用 new F ...

  3. Java_Swing中让窗口居中显示的方法(三种方法)

    方法一: int windowWidth = frame.getWidth(); // 获得窗口宽    int windowHeight = frame.getHeight(); // 获得窗口高 ...

  4. 编写Java程序,使用菜单组件制作一个记事本编辑器

    返回本章节 返回作业目录 需求说明: 使用菜单组件制作一个记事本编辑器 实现思路: 创建记事本菜单工具栏JMenuBar. 创建多个菜单条JMenu. 创建多个菜单项JMenuItem. 将菜单添加至 ...

  5. 初识python: 类练习 - 老板&员工

    需求: 1.员工具有姓名.年龄.能力值(能力值为100-年龄),可以工作,每工作一次,该员工的能力值-5,创建__str__方法,打印该员工的信息: 2.老板具有投资金额,工作量,员工列表.可以雇佣员 ...

  6. Flask_Flask-Migrate数据迁移扩展(十二)

    在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库.最直接的方式就是删除旧表,但这样会丢失数据.更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化,然后把变动应用到数据库中. ...

  7. 深入研究 synchronized 同步锁 作用于 静态方法 和 非静态方法 的 区别

    1.前言 众所周知, synchronized 是同步锁 ,虽然在底层又细分了无锁.偏向锁.轻量级锁.自旋锁 以及重量级锁 机制, 这些底层锁知道一下原理即可 ,[想要 了解 这篇 博文 有 解释 : ...

  8. SQL高级优化(一)之MySQL优化

    不同方案效率对比 MySQL各字段默认长度(一字节为8位) 整型: TINYINT 1 字节 SMALLINT 2 个字节 MEDIUMINT 3 个字节 INT 4 个字节 INTEGER 4 个字 ...

  9. vue特效网站集锦

    1.17素材网 http://www.17sucai.com/pins/tag/7012.html

  10. 【Java】GUI实现贪吃蛇

    [Java]GUI实现贪吃蛇 前言 我们在做这个小游戏之前,得确保自己的AWT和Swing有一定的基础,并且会写一些简单的逻辑操作.这些都会在后面写的时候体现出来. 狂神老师从这里开始讲贪吃蛇的 我们 ...