java线程之间的控制,使用Semaphore 实现 互斥

2024-06-20 16:58

本文主要是介绍java线程之间的控制,使用Semaphore 实现 互斥,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本来准备通过例子,从自己实现到最后使用并发工具实现,但是貌似效果并不是很好,有点太啰嗦的感觉,所有准备直入主题。

介绍:Semaphore中管理着一组虚拟的许可,许可的初始数量可通过构造函数来指定【new Semaphore(1);】,执行操作时可以首先获得许可【semaphore.acquire();】,并在使用后释放许可【semaphore.release();】。如果没有许可,那么acquire方法将会一直阻塞直到有许可(或者直到被终端或者操作超时)。

作用:可以用来控制同时访问某个特定资源的操作数量,或者某个操作的数量。

下面使用Semaphore实现两个例子:

1、互斥

大家都学过操作系统,都知道互斥的概念,比较简单的互斥实现,比如PV操作,判断资源,然后忙等实现互斥;上一篇博客也说过,忙等对CPU的消耗巨大,下面我们通过Semaphore来实现一个比较好的互斥操作:

假设我们公司只有一台打印机,我们需要对这台打印机的打印操作进行互斥控制:

[java]  view plain copy
  1. package com.zhy.concurrency.semaphore;  
  2.   
  3. import java.util.concurrent.Semaphore;  
  4.   
  5. /** 
  6.  * 使用信号量机制,实现互斥访问打印机 
  7.  *  
  8.  * @author zhy 
  9.  *  
  10.  */  
  11. public class MutexPrint  
  12. {  
  13.   
  14.     /** 
  15.      * 定义初始值为1的信号量 
  16.      */  
  17.     private final Semaphore semaphore = new Semaphore(1);  
  18.   
  19.     /** 
  20.      * 模拟打印操作 
  21.      * @param str 
  22.      * @throws InterruptedException 
  23.      */  
  24.     public void print(String str) throws InterruptedException  
  25.     {  
  26.         //请求许可  
  27.         semaphore.acquire();  
  28.           
  29.         System.out.println(Thread.currentThread().getName()+" enter ...");  
  30.         Thread.sleep(1000);  
  31.         System.out.println(Thread.currentThread().getName() + "正在打印 ..." + str);  
  32.         System.out.println(Thread.currentThread().getName()+" out ...");  
  33.         //释放许可  
  34.         semaphore.release();  
  35.     }  
  36.   
  37.     public static void main(String[] args)  
  38.     {  
  39.         final MutexPrint print = new MutexPrint();  
  40.   
  41.         /** 
  42.          * 开启10个线程,抢占打印机 
  43.          */  
  44.         for (int i = 0; i < 10; i++)  
  45.         {  
  46.             new Thread()  
  47.             {  
  48.                 public void run()  
  49.                 {  
  50.                     try  
  51.                     {  
  52.                         print.print("helloworld");  
  53.                     } catch (InterruptedException e)  
  54.                     {  
  55.                         e.printStackTrace();  
  56.                     }  
  57.                 };  
  58.             }.start();  
  59.         }  
  60.   
  61.     }  
  62.   
  63. }  

输出结果:

[java]  view plain copy
  1. Thread-1 enter ...  
  2. Thread-1正在打印 ...helloworld  
  3. Thread-1 out ...  
  4. Thread-2 enter ...  
  5. Thread-2正在打印 ...helloworld  
  6. Thread-2 out ...  
  7. Thread-0 enter ...  
  8. Thread-0正在打印 ...helloworld  
  9. Thread-0 out ...  
  10. Thread-3 enter ...  
  11. Thread-3正在打印 ...helloworld  
  12. Thread-3 out ...  

通过初始值为1的Semaphore,很好的实现了资源的互斥访问。

这篇关于java线程之间的控制,使用Semaphore 实现 互斥的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1078715

相关文章

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

Python实现AVIF图片与其他图片格式间的批量转换

《Python实现AVIF图片与其他图片格式间的批量转换》这篇文章主要为大家详细介绍了如何使用Pillow库实现AVIF与其他格式的相互转换,即将AVIF转换为常见的格式,比如JPG或PNG,需要的小... 目录环境配置1.将单个 AVIF 图片转换为 JPG 和 PNG2.批量转换目录下所有 AVIF 图

Pydantic中Optional 和Union类型的使用

《Pydantic中Optional和Union类型的使用》本文主要介绍了Pydantic中Optional和Union类型的使用,这两者在处理可选字段和多类型字段时尤为重要,文中通过示例代码介绍的... 目录简介Optional 类型Union 类型Optional 和 Union 的组合总结简介Pyd

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

Pydantic中model_validator的实现

《Pydantic中model_validator的实现》本文主要介绍了Pydantic中model_validator的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录引言基础知识创建 Pydantic 模型使用 model_validator 装饰器高级用法mo

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

Spring Security方法级安全控制@PreAuthorize注解的灵活运用小结

《SpringSecurity方法级安全控制@PreAuthorize注解的灵活运用小结》本文将带着大家讲解@PreAuthorize注解的核心原理、SpEL表达式机制,并通过的示例代码演示如... 目录1. 前言2. @PreAuthorize 注解简介3. @PreAuthorize 核心原理解析拦截与