电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

交通灯管理系统


发布日期:2020/10/16
 
模拟实现十字路口的交通灯管理系统逻辑具体需求如下

异步随机生成按照各个路线行驶的车辆

例如

由南向而来去往北向的车辆 直行车辆

由西向而来去往南向的车辆 右转车辆

由东向而来去往南向的车辆 左转车辆

信号灯忽略黄灯只考虑红灯和绿灯

应考虑左转车辆控制信号灯右转车辆不受信号灯控制

具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同不考虑特殊情况下的控制逻辑

南北向车辆与东西向车辆交替放行同方向等待车辆应先放行直行车辆而后放行左转车辆

每辆车通过路口时间为秒(提示可通过线程Sleep的方式模拟)

随机生成车辆时间间隔以及红绿灯交换时间间隔自定可以设置

不要求实现GUI只考虑系统逻辑实现可通过Log方式展现程序运行结果

在这里面需要弄三个类Road;Lamp;LampController;mainClass

Road

每个Road对象都有一个name成员变量来代表方向有一个vehicles成员变量来代表方向上的车辆集合

在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个路线名_id形式的字符串进行表示)

在Road对象的构造方法中启动一个定时器每隔一秒检查该方向上的灯是否为绿是则打印车辆集合和将集合中的第一辆车移除掉

package comtaobaointerview;

import javautilArrayList;

import javautilList;

import javautilRandom;

import ncurrentExecutorService;

import ncurrentExecutors;

import ncurrentScheduledExecutorService;

import ncurrentTimeUnit;

public class Road {

private String name;

private List<String> vechicles = new ArrayList<String>()

public Road(String name){

thisname = name;

ExecutorService pool = ExecutorsnewSingleThreadExecutor()

poolexecute(new Runnable() {

@Override

public void run() {

for(int i=;i<;i++){

try {

Threadsleep(new Random()nextInt()*

vechiclesadd(Roadthisname+i)

} catch (InterruptedException e) {

// TODO Autogenerated catch block

eprintStackTrace()

}

}

}

})

ScheduledExecutorService timer = ExecutorsnewScheduledThreadPool(

timerscheduleAtFixedRate(new Runnable() {

@Override

public void run() {

if(vechiclessize()> && LampvalueOf(Roadthisname)isLighted())

Systemoutprintln(vechiclesremove()+有车行驶

}

}

TimeUnitSECONDS)

}

}

Lamp

系统中有个方向上的灯在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象综合这些因素将Lamp类用java中的枚举形式定义更为简单

每个Lamp对象中的亮黑状态用lighted变量表示选用SNSWEWEN这四个方向上的Lamp对象依次轮询变亮Lamp对象中还要有一个oppositeLampName变量来表示它们相反方向的灯再用一个nextLampName变量来表示此灯变亮后的下一个变亮的灯这三个变量用构造方法的形式进行赋值因为枚举元素必须在定义之后引用所以无法再构造方法中彼此相互引用所以相反方向和下一个方向的灯用字符串形式表示

增加让Lamp变亮和变黑的方法light和blackOut对于SNSWEWEN这四个方向上的Lamp对象这两个方法内部要让相反方向的灯随之变亮和变黑blackOut方法还要让下一个灯变亮

除了SNSWEWEN这四个方向上的Lamp对象之外其他方向上的Lamp对象的nextLampName和oppositeLampName属性设置为null即可并且SNSWEWEN这四个方向上的Lamp对象的nextLampName和oppositeLampName属性必须设置为null以便防止light和blackOut进入死循环

package comtaobaointerview;

public enum Lamp {

SN(NSfalseSWSW(NEfalseEWEW(WEfalseESES(WNfalseSN

NS(nullfalsenull)NE(nullfalsenull)WE(nullfalsenull)WN(nullfalsenull)

WS(nulltruenull)SE(nulltruenull)EN(nulltruenull)NW(nulltruenull)

private String opposite;

private String next;

private boolean lighted;

private Lamp(String oppostieboolean lightedString next){

thisopposite = oppostie;

thislighted = lighted;

thisnext = next;

}

public void light(){

lighted = true;

if(opposite!=null){

Lamp oppLamp = LampvalueOf(opposite)

oppLamplight()

}

Systemoutprintln(thisname()+方向绿灯亮了可以行驶

}

public Lamp black(){

lighted = false;

Lamp nextLamp = null;

if(opposite!=null){

LampvalueOf(opposite)black()

}

if(next!=null){

Systemoutprintln(next)

nextLamp = LampvalueOf(next)

nextLamplight()

}

return nextLamp;

}

public boolean isLighted(){

return lighted;

}

}

LampController

整个系统中只能有一套交通灯控制系统所以LampController类最好是设计成单例

LampController构造方法中要设定第一个为绿的灯

LampController对象的start方法中将当前灯变绿然后启动一个定时器每隔秒将当前灯变红和将下一个灯变绿

package comtaobaointerview;

import ncurrentExecutor;

import ncurrentExecutors;

import ncurrentScheduledExecutorService;

import ncurrentTimeUnit;

public class LampController {

private Lamp currentLamp;

public LampController(){

currentLamp = LampSN;

currentLamplight()

ScheduledExecutorService timer = ExecutorsnewScheduledThreadPool(

timerscheduleAtFixedRate(new Runnable(){

public void run(){

currentLamp = currentLampblack()

}

}

TimeUnitSECONDS)

}

}

总结

每条路线上都会出现多辆车路线上要随机增加新的车在灯绿期间还要每秒钟减少一辆车

设计一个Road类来表示路线每个Road对象代表一条路线总共有条路线即系统中总共要产生个Road实例对象

每条路线上随机增加新的车辆增加到一个集合中保存

每条路线每隔一秒都会检查控制本路线的灯是否为绿是则将本路线保存车的集合中的第一辆车移除即表示车穿过了路口

每条路线每隔一秒都会检查控制本路线的灯是否为绿一个灯由绿变红时应该将下一个方向的灯变绿

设计一个Lamp类来表示一个交通灯每个交通灯都维护一个状态亮(绿)或不亮(红)每个交通灯要有变亮和变黑的方法并且能返回自己的亮黑状态

总共有条路线所以系统中总共要产生个交通灯右拐弯的路线本来不受灯的控制但是为了让程序采用统一的处理方式故假设出有四个右拐弯的灯只是这些灯为常亮状态即永远不变黑

除了右拐弯方向的其他条路线的灯它们是两两成对的可以归为所以在编程处理时只要从这组中各取出一个灯对这个灯依次轮询变亮与这个灯方向对应的灯则随之一同变化因此Lamp类中要有一个变量来记住自己相反方向的灯在一个Lamp对象的变亮和变黑方法中将对应方向的灯也变亮和变黑每个灯变黑时都伴随者下一个灯的变亮Lamp类中还用一个变量来记住自己的下一个灯

无论在程序的什么地方去获得某个方向的灯时每次获得的都是同一个实例对象所以Lamp类改用枚举来做显然具有很大的方便性永远都只有代表个方向的灯的实例对象

设计一个LampController类它定时让当前的绿灯变红

这是一个很好的题收获很多

上一篇:让人抓狂匪夷所思的4组代码

下一篇:如何实现Applet之间跨浏览器窗口的通信