原创:转载需注明原创地址 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. Java初学者作业——完成对已定义类(Admin)的对象的创建。并完成属性的赋值和方法的调用。

    返回本章节 返回作业目录 需求说明: 完成对已定义类(Admin)的对象的创建.并完成属性的赋值和方法的调用. 实现思路: 创建 MyTest 类,并添加 main函数. 在 main函数中完成对 A ...

  2. .NET 编码的基础知识

    .NET 编码的一些基本概念和分析 简单的类型概念 Hex (16进制) byte 字节 范围是:0~255,二进制下的范围就是00000000~11111111,相当于1字节. byte[] 字节数 ...

  3. 数学库Sage安装和使用

    什么是Sage? Sage是免费的.开源的数学软件,支持代数.几何.数论.密码学.数值计算和相关领域的研究和教学. 可以简单看成一个数学库 下载 国内地址 安装 Windows下安装 下载安装程序即可 ...

  4. c# - 接口的写法与基本调用

    1.前言 接口与Java基本一样 2.操作 (1)看路径结果 (2) 接口源码: namespace ConsoleApp1 { public interface ILogin { void Eat( ...

  5. Go语言系列之标准库path/filepath

    一.Path包 import "path" path实现了对斜杠分隔的路径进行操作的函数. func IsAbs(path string) bool // 判断是否是一个绝对路径 ...

  6. vue 前进刷新后退不刷新

    这边是router-view部门的写法: <keep-alive> <router-view v-if="$route.meta.keepAlive"/> ...

  7. 树莓派和荔枝派,局域网socket 通信

    在虚拟机上面实现了socket 之间的通信之后,突发奇想,想要实现树莓派和 荔枝派zero之间的通信. 1.直接将虚拟机下面的程序复制过来,重新编译并且运行.发现是没有办法进行通信的.客户端一直报错: ...

  8. Android中添加监听回调接口的方法

    在Android中,我们经常会添加一些监听回调的接口供别的类来回调,比如自定义一个PopupWindow,需要让new这个PopupWindow的Activity来监听PopupWindow中的一些组 ...

  9. 使用.NET 6开发TodoList应用(填坑1)——实现当前登录用户获取

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在前面的文章里使用.NET 6开发TodoList应用(5)--领域实体创建,我们留了一个坑还没有填上,就是在数据库保存的时候 ...

  10. Spring boot + Vue axios 文件下载

    后端代码: @GetMapping("/{sn}") @ApiOperation(value = "获取文件",notes = "获取文件" ...