当前位置: 首页 > news >正文

Java 信号量机制实现

Java 信号量机制实现

信号量 Semaphore

信号量可限制访问共享资源的线程数。线程访问资源前需从信号量获取许可,访问结束后需将许可归还信号量。
image

场景介绍

一个停车场只有5个车位,现有100辆车争抢这5个车位。理想情况下,最多同时有5辆车能抢到车位,未抢到车位的车需等待,直到其他车让出车位后才有机会使用。

实现代码

package com.semaphore;import java.util.concurrent.*;/*** @author Jing61*/
public class CarPark {public static void main(String[] args) {//阻塞队列BlockingQueue<String> parks = new LinkedBlockingQueue<>(5);parks.offer("车位一");parks.offer("车位二");parks.offer("车位三");parks.offer("车位四");parks.offer("车位五");ExecutorService executorService = Executors.newCachedThreadPool();// 5个车位(许可)Semaphore semaphore = new Semaphore(5);for (int i = 0; i < 100; i++) {final int no = i;Thread t1 = new Thread(() -> {try {/*** 获取许可,首先判断semaphore内部的数字是否大于0,如果大于0,* 才能获得许可,然后将初始值5减去1,线程才会接着去执行;如果没有* 获得许可(原因是因为已经有5个线程获得到许可,semaphore内部的数字为0),* 线程会阻塞直到已经获得到许可的线程,调用release()方法,释放掉许可,* 也就是将semaphore内部的数字加1,该线程才有可能获得许可。*/semaphore.acquire();/***  对应的线程会到阻塞对,对应车辆去获取到车位,如果没有拿到一致阻塞,*  直到其他车辆归还车位。*/String park = parks.take();  System.out.println("车辆【" + no + "】获取到: " + park);Thread.sleep((long) Math.random() * 6000);System.out.println("车辆【" + no + "】离开 " + park);semaphore.release(); //线程释放掉许可,通俗来将就是将semaphore内部的数字加1parks.offer(park);  //归还车位} catch (InterruptedException e) {e.printStackTrace();}});executorService.execute(t1);}executorService.shutdown();}
}

哲学家进餐问题

1965年,荷兰计算机科学家、图灵奖得主Edsger Wybe Dijkstra提出并解决了“哲学家进餐”同步问题。

问题描述

五个哲学家围坐在圆桌旁,每人面前有一盘通心粉。由于通心粉较滑,需两把叉子才能夹住。相邻两个盘子之间放有一把叉子(如下图所示)。

image

哲学家的生活有两种交替活动:吃饭和思考。当哲学家感到饥饿时,会尝试分两次取左右两边的叉子(每次拿一把,不分次序)。成功拿到两把叉子后开始吃饭,吃完后放下叉子继续思考。

若将哲学家替换为线程,叉子替换为竞争的临界资源,该问题即为线程竞争资源问题。若设计不当,系统可能出现死锁、活锁、吞吐量下降等问题。

信号量原语解决方案(Java 实现)

以下是使用 Java 5 并发工具包中的 Semaphore 类解决哲学家进餐问题的代码:

package com.wise.tiger;import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;/*** 存放线程共享信号量上下文* @author Jing61*/
public class SemaphoreContext {public static final int NUM_OF_FORKS = 5;//叉子数量(资源)public static final int NUM_OF_PHILO = 5;//哲学家数量(线程)public static Semaphore[] forks;public static Semaphore counter;static{forks = new Semaphore[NUM_OF_FORKS];for(int i = 0 ; i < forks.length; i++){forks[i] = new Semaphore(1);}counter = new Semaphore(NUM_OF_PHILO - 1);}public static void putFork(int index,boolean leftFirst) throws Exception{if(leftFirst) {forks[index].acquire();forks[(index + 1) % NUM_OF_PHILO].acquire();}else {forks[(index + 1) % NUM_OF_PHILO].acquire();forks[index].acquire();}}public static void takeFork(int index,boolean leftFirst) throws Exception{if(leftFirst) {forks[index].release();forks[(index + 1) % NUM_OF_PHILO].release();}else {forks[(index + 1) % NUM_OF_PHILO].release();forks[index].release();}}static class Philo implements Runnable{private int index;private String name;public Philo(int index, String name) {this.index = index;this.name = name;}@Overridepublic void run() {while (true) {try {counter.acquire();boolean isLeftFirst = index % 2 == 0;putFork(index, isLeftFirst);System.out.println(name + "正在吃通心粉。。。。。");takeFork(index, isLeftFirst);System.out.println(name + "吃完了,正在思考");counter.release();} catch (Exception e) {e.printStackTrace();}}}}public static void main(String[] args) {Philo[] philos = {new Philo(0,"peppa"),new Philo(1,"pedro"),new Philo(2,"emily"),new Philo(3,"suzy"),new Philo(4,"danny"),};var pool = Executors.newCachedThreadPool();for(int i= 0; i < philos.length;i++){pool.execute(philos[i]);}pool.shutdown();}
}
http://www.jsqmd.com/news/40301/

相关文章:

  • lc:338练习的一点思考
  • 京东商品评论接口深度逆向:从加密参数破解到情感倾向分析
  • [LangChian] 18. 自动维护聊天记录
  • 二进制掩码规律
  • jenkins构建生成docker镜像
  • 在线文档大全
  • AI大事记12:Transformer 架构——重塑 NLP 的革命性技能(下)
  • 记一次多线程插入或者更新数据库表操作优化过程
  • 2025年进口干冰机代理工厂权威推荐榜单:干冰清洗机/干冰制造机源头厂家精选
  • 接口调试利器,Postman免安装,免登陆 - 详解
  • 微算法科技(NASDAQ MLGO)在委托权益证明DPoS主链上引入PoW轻节点验证,提升抗量子攻击能力
  • 字的bi-gram可能是个馊主意
  • 常见的几种硬盘接口类型
  • 2025年w70钨铜棒制造企业权威推荐榜单:钨铜导电块/钨铜块/93钨合金源头厂家精选
  • 嵌入式系统profinet转devicenet固件与硬件接口的连接案例
  • KMPlayer下载教程(2025新版)——全功能安装配置与使用经验详解
  • 一个通过强制使用符号来避免链接器忽略符号的方法
  • 安卓非原创--基于Android Studio 实现的天气预报App - 教程
  • 10.7万条轨迹+4大机器人构型!RoboMIND开源数据集破解机器人通用操作难题 | 附一键复现指南
  • 2025年全屋定制橱柜优质厂家权威推荐榜单:全屋定制门窗/高端整装定制/整装全屋定制源头厂家精选
  • c++初学者的随笔记录_4
  • 2025 最新多孔筋增强管生产线厂家权威推荐:国际测评认证 + 技术创新双驱,全周期服务优选榜单缠绕管承插口生产线 / 承插口注塑设备生产线公司推荐
  • 自动化控制Devicenet转Profinet—PLC分布式控制架构的网关连接案例
  • 2025年专业的卷被机工厂权威推荐榜单:好的卷被机/不错的卷被机/卷被机品牌厂家精选
  • 工业网络通信中profinet转devicenet基于总线协议转换的网关连接技术研究
  • 2025 年 11 月 Pogopin 弹簧针厂家推荐排行榜,精密测试针,医疗传感器,手机连接器,声学弹簧,触摸仪表,手表锁具,座椅检测优质公司推荐
  • 国标GB28181算法算力平台EasyGBS如何赋能现代应急指挥体系?
  • 2025 年钢结构源头厂家最新推荐排行榜:聚焦全产业链服务与核心产能,七大实力企业权威甄选
  • xcode 打包 报错 main.jsbundle does not exist.
  • 2025年简易激光切管机供应商权威推荐榜单:高速激光切管机/拉料式激光切管机/迷你激光切管机设备源头厂家精选