java 信号量Semaphore的使用

2024-09-03 00:48

本文主要是介绍java 信号量Semaphore的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java 信号量Semaphore的使用

信号量是一种计数器,用来保护一个或者多个共享资源的访问。

信号量的使用:

(1)如果一个线程要访问一个共享资源,他必须先获得信号量。如果信号量的内部计数器大于0,信号量将减1,然后允许访问这个共享资源。计数器大于0意味着又可以使用的资源,因此线程讲被允许使用其中一个资源。

(2)如果信号量等于0,信号将将会把线程植入休眠直到计数器大于0.计数器等于0的时候意味着所有的共享资源已经被其他线程使用了,所以需要访问这个共享资源的线程必须等待。

(3)当线程使用完这个共享资源时,信号量必须被释放,以便其他线程能够访问共享资源,释放操作将使用信号量的内部计数器增加1。

本节教你,在java中如何实现java的Semaphore信号量类,主要用到Semaphore类的acquire()方法和release()方法,分别是获取资源和释放资源的意思,最后我会解释Semaphore类的源码作分析。

我们的演示例子功能是:我们将实现一个打印队列,并发任务将使用它来完成打印。这个打印队列受信号量保护,因而同一时刻只有一个线程可以执行打印。

代码如下:

package test1;import java.util.concurrent.Semaphore;public class SemaphoreDemo {public static void main(String[] args) {PrintQueue printQueue = new PrintQueue();Thread thread[] = new Thread[10];for (int i = 0; i < 10; i++) {thread[i] = new Thread(new Job(printQueue),"Thread"+i);}for (int i = 0; i < 10; i++) {thread[i].start();}}}class PrintQueue {private final Semaphore semaphore;public PrintQueue() {semaphore = new Semaphore(1);//这是一个二进制信号量哦,计数器值只能是0或者1;}public void printJob (Object document) {try {semaphore.acquire();//获取共享资源,如果计数器为0会等待long duration = (long) (Math.random()*10);System.out.printf("%s: PrintQueue: Printing a job during %d seconds \n",Thread.currentThread().getName(),duration);Thread.sleep(duration);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release();//放在finally语句块表示不管发不发生异常都会执行,都会释放资源。}}
}class Job implements Runnable {private PrintQueue printQueue;public Job(PrintQueue printQueue) {this.printQueue = printQueue;}@Override public void run() {System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());printQueue.printJob(new Object());System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());}
}

输出结果:

Thread1: Going to print a job
Thread9: Going to print a job
Thread8: Going to print a job
Thread7: Going to print a job
Thread5: Going to print a job
Thread3: Going to print a job
Thread6: Going to print a job
Thread4: Going to print a job
Thread2: Going to print a job
Thread0: Going to print a job
Thread1: PrintQueue: Printing a job during 4 seconds 
Thread1: The document has been printed
Thread9: PrintQueue: Printing a job during 6 seconds 
Thread9: The document has been printed
Thread8: PrintQueue: Printing a job during 4 seconds 
Thread8: The document has been printed
Thread7: PrintQueue: Printing a job during 6 seconds 
Thread7: The document has been printed
Thread5: PrintQueue: Printing a job during 3 seconds 
Thread5: The document has been printed
Thread3: PrintQueue: Printing a job during 2 seconds 
Thread3: The document has been printed
Thread6: PrintQueue: Printing a job during 9 seconds 
Thread6: The document has been printed
Thread4: PrintQueue: Printing a job during 3 seconds 
Thread4: The document has been printed
Thread2: PrintQueue: Printing a job during 1 seconds 
Thread2: The document has been printed
Thread0: PrintQueue: Printing a job during 3 seconds 
Thread0: The document has been printed


仔细看看结果哦,一开始大家都在等待,只能一个一个打印哦;



这篇关于java 信号量Semaphore的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131546

相关文章

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red