【LeetCode-多线程】1279. 红绿灯路口
目录
- 一、题目
- 二、解决
- 1、synchronized
- 2、CAS
- 3、Lock
- 4、信号量
- 三、参考
一、题目
这是两条路的交叉路口。第一条路是 A 路,车辆可沿 1 号方向由北向南行驶,也可沿 2 号方向由南向北行驶。第二条路是 B 路,车辆可沿 3 号方向由西向东行驶,也可沿 4 号方向由东向西行驶。
每条路在路口前都有一个红绿灯。红绿灯可以亮起红灯或绿灯。
- 绿灯表示两个方向的车辆都可通过路口。
- 红灯表示两个方向的车辆都不可以通过路口,必须等待绿灯亮起。
两条路上的红绿灯不可以同时为绿灯。这意味着,当 A 路上的绿灯亮起时,B 路上的红灯会亮起;当 B 路上的绿灯亮起时,A 路上的红灯会亮起.
开始时,A 路上的绿灯亮起,B 路上的红灯亮起。当一条路上的绿灯亮起时,所有车辆都可以从任意两个方向通过路口,直到另一条路上的绿灯亮起。不同路上的车辆不可以同时通过路口。
给这个路口设计一个没有死锁的红绿灯控制系统。
实现函数 void carArrived(carId, roadId, direction, turnGreen, crossCar)
:
carId
为到达车辆的编号。roadId
为车辆所在道路的编号。direction
为车辆的行进方向。turnGreen
是一个函数,调用此函数会使当前道路上的绿灯亮起。crossCar
是一个函数,调用此函数会允许车辆通过路口。
当你的答案避免了车辆在路口出现死锁,此答案会被认定为正确的。当路口已经亮起绿灯时仍打开绿灯,此答案会被认定为错误的。
示例 1:
输入: cars = [1,3,5,2,4], directions = [2,1,2,4,3], arrivalTimes = [10,20,30,40,50]
输出: [
"Car 1 Has Passed Road A In Direction 2", // A 路上的红绿灯为绿色,1 号车可通过路口。
"Car 3 Has Passed Road A In Direction 1", // 红绿灯仍为绿色,3 号车通过路口。
"Car 5 Has Passed Road A In Direction 2", // 红绿灯仍为绿色,5 号车通过路口。
"Traffic Light On Road B Is Green", // 2 号车在 B 路请求绿灯。
"Car 2 Has Passed Road B In Direction 4", // B 路上的绿灯现已亮起,2 号车通过路口。
"Car 4 Has Passed Road B In Direction 3" // 红绿灯仍为绿色,4 号车通过路口。
]
示例 2:
输入: cars = [1,2,3,4,5], directions = [2,4,3,3,1], arrivalTimes = [10,20,30,40,40]
输出: [
"Car 1 Has Passed Road A In Direction 2", // A 路上的红绿灯为绿色,1 号车可通过路口。
"Traffic Light On Road B Is Green", // 2 号车在 B 路请求绿灯。
"Car 2 Has Passed Road B In Direction 4", // B 路上的绿灯现已亮起,2 号车通过路口。
"Car 3 Has Passed Road B In Direction 3", // B 路上的绿灯现已亮起,3 号车通过路口。
"Traffic Light On Road A Is Green", // 5 号车在 A 路请求绿灯。
"Car 5 Has Passed Road A In Direction 1", // A 路上的绿灯现已亮起,5 号车通过路口。
"Traffic Light On Road B Is Green", // 4 号车在 B 路请求绿灯。4 号车在路口等灯,直到 5 号车通过路口,B 路的绿灯亮起。
"Car 4 Has Passed Road B In Direction 3" // B 路上的绿灯现已亮起,4 号车通过路口。
]
解释: 这是一个无死锁的方案。注意,在 A 路上的绿灯亮起、5 号车通过前让 4 号车通过,也是一个正确且可被接受的方案。
提示:
1 <= cars.length <= 20
cars.length = directions.length
cars.length = arrivalTimes.length
cars
中的所有值都是唯一的。1 <= directions[i] <= 4
arrivalTimes
是非递减的。
二、解决
1、synchronized
思路:
题意总结如下:
- 十字路口由两条路组成 Road1 和 Road2
- 只有路灯才允许车辆通过,红灯则不行
我们可以构建一个临界区,每次只允许在一条路上通过,设置一个布尔变量 road1GreenOn
- 当 road1GreenOn == true 表示 Road1 是路灯
- 当 road1GreenOn == true 表示 Road2 是路灯
这里介绍四种实现方式:Synchronized 、Lock、CAS、 Semaphore(信号量)
代码:
class TrafficLight {public TrafficLight() {}boolean road1IsGreen = true;public synchronized void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection ) {if ((roadId == 1) != road1IsGreen) {turnGreen.run();road1IsGreen = !road1IsGreen;}crossCar.run();}
}
class TrafficLight {private final Object LOCK = new Object();private boolean road1GreenOn = false;public TrafficLight() {}public void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection) {synchronized (LOCK) {try {if (roadId == 1 && road1GreenOn) {turnGreen.run();road1GreenOn = false;} else if (roadId == 2 && !road1GreenOn) {turnGreen.run();road1GreenOn = true;}crossCar.run();} catch (Exception e) {}}}
}
2、CAS
思路: 略。
代码:
class TrafficLight {private final AtomicInteger atomic = new AtomicInteger();private boolean road1GreeOn = false;public TrafficLight() {}public void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection) {try {while (!atomic.compareAndSet(0, 1)) Thread.sleep(1);if (roadId == 1 && road1GreeOn) {turnGreen.run();road1GreeOn = false;} else if (roadId == 2 && !road1GreeOn) {turnGreen.run();road1GreeOn = true;}crossCar.run();while (!atomic.compareAndSet(1, 0)) Thread.sleep(1);} catch (Exception e) {}}
}
3、Lock
思路: 略。
代码:
class TrafficLight {private final Lock lock = new ReentrantLock();private boolean road1GreenOn = false;public TrafficLight() {}public void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection) {lock.lock();try {if (roadId == 1 && road1GreenOn) {turnGreen.run();road1GreenOn = false;} else if (roadId == 2 && !road1GreenOn) {turnGreen.run();road1GreenOn = true;}crossCar.run();} catch (Exception e) {} finally {lock.unlock();}}
}
4、信号量
思路: 略。
代码-版本1:
class TrafficLight {private Semaphore greenLight;//红绿灯遥控器private boolean road1CanGo;//表示道路1是绿灯private boolean road2CanGo;//表示道路2是绿灯public TrafficLight() {this.greenLight = new Semaphore(1, true);this.road1CanGo = true;this.road2CanGo = false;}public void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection) {try {greenLight.acquire();//申请获取遥控器//如果当前车道已经是绿灯了,直接通过if ((roadId == 1 && road1CanGo) || (roadId == 2 && road2CanGo)) crossCar.run();else if (roadId == 1 && !road1CanGo) {//否则,如果道路1不是绿灯,用遥控器变成绿灯turnGreen.run();road1CanGo = true;road2CanGo = false;crossCar.run();} else if (roadId == 2 && !road2CanGo) {//如果道路2不是绿灯,用遥控器变成绿灯turnGreen.run();road2CanGo = true;road1CanGo = false;crossCar.run();}greenLight.release();//最后把遥控器归还} catch (InterruptedException e) {e.printStackTrace();}}
}
代码-版本2:
class TrafficLight {private final Semaphore semaphore = new Semaphore(1);private boolean road1GreenOn = false;public TrafficLight() {}public void carArrived(int carId, // ID of the carint roadId, // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)int direction, // Direction of the carRunnable turnGreen, // Use turnGreen.run() to turn light to green on current roadRunnable crossCar // Use crossCar.run() to make car cross the intersection) {try {semaphore.acquire();if (roadId == 1 && road1GreenOn) {turnGreen.run();road1GreenOn = false;} else if (roadId == 2 && !road1GreenOn) {turnGreen.run();road1GreenOn = true;}crossCar.run();semaphore.release();} catch (Exception e) {}}
}
三、参考
1、4行代码 10ms
2、四种实现方式(cas、Lock、Semaphore、Synchronized)
3、Java 信号量思路
【LeetCode-多线程】1279. 红绿灯路口相关推荐
- LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
目录 1114. 按序打印 解法 1115. 交替打印FooBar 解法 1116. 打印零与奇偶数 解法 1117. H2O 生成 解法 1118. 设计有限阻塞队列 解法 1195. 交替打印字符 ...
- 畅游多线程之红绿灯路口
1279 红绿灯路口 每条路在路口前都有一个红绿灯.红绿灯可以亮起红灯或绿灯.绿灯表示两个方向的车辆都可通过路口. 红灯表示两个方向的车辆都不可以通过路口,必须等待绿灯亮起. 两条路上的红绿灯不可以同 ...
- LeetCode(多线程)- 1279. 红绿灯路口
题目链接:点击打开链接 题目大意:略. 解题思路:略. 相关企业 亚马逊(Amazon) 高盛集团(Goldman Sachs) 苹果(Apple) 微软(Microsoft) 谷歌(Google) ...
- 1279 红绿灯路口
题目描述: 这是两条路的交叉路口.第一条路是 A 路,车辆可沿 1 号方向由北向南行驶,也可沿 2 号方向由南向北行驶.第二条路是 B 路,车辆可沿 3 号方向由西向东行驶,也可沿 4 号方向由东向西 ...
- 坡道行驶电动小车_事发红绿灯路口!东莞一女子骑电动滑板车被撞致颅内出血…...
东莞的小伙伴们应该都在路上见过电动滑板车一些上班族平时都用它代步但大家在享受电动滑板车的便捷时一定要提高安全意识否则就容易发生意外!事件回顾近日在东莞厚街S256省道濠畔红绿灯路口发生一起电动滑板车与 ...
- 科目三 临时停车 与 红绿灯 路口 LTS
科目三 临时停车 与 红绿灯 路口 LTS 临时停车 ,需要双闪不 昨天考挂了,绿灯还有12妙没有过,安全员判定不合格 教练说十秒内可以停/ 2挡不超30码就不会出现档位车速不配色.红绿灯也没规定挂空 ...
- LeetCode题解(1279):红绿灯路口(Python)
题目:原题链接(简单) 标签:多线程 解法 时间复杂度 空间复杂度 执行用时 Ans 1 (Python) O(N)O(N)O(N) O(1)O(1)O(1) 52ms (88.89%) Ans 2 ...
- Leetcode_1279_红绿灯路口_多线程
用一个布尔型变量保存目前红绿灯状态. 如果目前的车能通过红绿灯,就让他通过. 如果不能,改变灯的状态. class TrafficLight {boolean isAGreen; public Tra ...
- LeetCode-1279. 红绿灯路口
这是两条路的交叉路口.第一条路是 A 路,车辆可沿 1 号方向由北向南行驶,也可沿 2 号方向由南向北行驶.第二条路是 B 路,车辆可沿 3 号方向由西向东行驶,也可沿 4 号方向由东向西行驶. 每条 ...
最新文章
- matlab 集成学习方法,将simulink集成到matlab脚本中
- [Redux/Mobx] Redux和vuex有什么区别?
- 【LeetCode】【HOT】394. 字符串解码(栈)
- Promise编程基础
- windows 2013 datacenter 安装sql server2008 r2兼容性
- 国庆长假前不妨先来做完这份 JavaScript 测验吧!因为......
- 【PostgreSQL-9.6.3】修改监听的IP和端口
- MyBatis 3.5.1 发布,Java 数据持久层框架
- cvCalcEMD2() 直方图匹配
- 《电路》邱关源 思维导图 第三章 电阻电路的一般分析
- 分享五款好用的PDF编辑工具
- WIN10/WIN11 优启动 GHOST
- 指数分布java_终于搞清楚正态分布、指数分布到底是啥了!
- Linux系统文件颜色代表的意思
- golang http服务的graceful问题
- 云计算是什么?3分钟了解云计算技术
- AFML读书笔记--Sample weight
- sql查询语句中分组添加小计,GROUPING的使用
- 品优购电商系统开发 第5章 商品录入【1】
- java 字体大小 像素_字体的大小(pt)和像素(px)如何转换?
热门文章
- Self-Attention for CodeSearch
- 【ENOVIA】xCAD协同数据管理-Solid Edge | 达索系统百世慧®
- 资深建模师给萌新建模师的一些建议,必经之路,贵在坚持
- 华为的变革_实时3D如何推动整个行业的变革
- 戴森VR体验店:以科技开启未来无限可能 沉浸式购物场景,引领零售新体验
- C#坦克大战网络版代码
- ABP(ASP.NET Boilerplate Project)快速入门
- POJ1015陪审团(Jury Compromise)——dp+路径记录
- oracle中decode函数详细解释,oracle中的decode函数
- 系统状态查看工具Sysstat