畅游多线程之红绿灯路口

1279 红绿灯路口

请添加图片描述

每条路在路口前都有一个红绿灯。红绿灯可以亮起红灯或绿灯。

绿灯表示两个方向的车辆都可通过路口。
红灯表示两个方向的车辆都不可以通过路口,必须等待绿灯亮起。
两条路上的红绿灯不可以同时为绿灯。这意味着,当 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:Semaphore

class TrafficLight {

    private Semaphore semaphore = new Semaphore(1);
    boolean isAGreen = true;

    public void carArrived(
            int carId,           // ID of the car
            int roadId,          // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)
            int direction,       // Direction of the car
            Runnable turnGreen,  // Use turnGreen.run() to turn light to green on current road
            Runnable crossCar    // Use crossCar.run() to make car cross the intersection
    ) throws InterruptedException {
        semaphore.acquire();
        if (roadId == 2 && isAGreen || roadId == 1 && !isAGreen) {
            turnGreen.run();
            isAGreen = !isAGreen;
        }
        crossCar.run();
        semaphore.release();
    }
}

方法2:变量

class TrafficLight {
    boolean isAGreen;

    public TrafficLight() {
        isAGreen = true;
    }

    synchronized public void carArrived(
            int carId,           // ID of the car
            int roadId,          // ID of the road the car travels on. Can be 1 (road A) or 2 (road B)
            int direction,       // Direction of the car
            Runnable turnGreen,  // Use turnGreen.run() to turn light to green on current road
            Runnable crossCar    // Use crossCar.run() to make car cross the intersection
    ) {
        if (roadId == 2 && isAGreen == true || roadId == 1 && isAGreen == false) {
            turnGreen.run();
            isAGreen = !isAGreen;
        }
        crossCar.run();
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值