一:系统实现
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:1.异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
2.信号灯忽略黄灯,只考虑红灯和绿灯
3.应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4. 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆
5.每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)
6.随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7.不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果
-------------------------------------------------------------------------------------------------------------------------
二.系统分析与设计
1.经分析,设计的类,路线,信号灯,交通灯控制;推理出三者之间关系,共12路线且每条路线不同的信号灯,即红灯时此路线车辆在增加,变为绿灯时此路线车辆在减少。2.设计思路以及模型
十字路口共12条路线,分别是南向北 、北向南、南向西、北向东、东向西、西向东、东向南、西向北,加上4个右拐弯南向东、东向北、北向西、西向南,即12个信号灯,据分析,其四条右拐路线的交通灯处于绿灯状态,剩余8条路线,根据路线方向对应相反分为一组,共分为4组,且每组路线上的灯状态一致,每组选一条路线的灯在某时刻轮流切换下一组灯的状态
路线的模型设计:名字描述,车辆缓冲池,通过异步完成车辆的增加,根据此路线灯状态为绿灯则移除
交通灯的设计模型设计: JDK1.5 新特性 枚举 完成此类设计,记录每个灯的状态,每组路线的灯状态一致,获取下一组路线其一个灯的状态,某时刻轮流切换灯的状态
交通灯控制模型设计:选取某条路线为当前灯,且为绿灯状态,定时10秒处理事务,轮流切换下一组路线其一个灯的状态
3.路线图分析

4.涉及知识:oop 设计分析,交通灯逻辑分析,枚举 新特性运用,并发库线程池处理线程数量,单线程调度延迟或某定期执行事务
思考 灯顺序实现过程:
开始从 (NORTH2SOUTH,SOUTH2NORTH),这组灯转到
左拐路线的灯
(NORTH2EAST,SOUTH2WEST),
南北路线车辆全部走完了
东西走向 转到 灯(EAST2WEST,WEST2EAST),
这组红灯就到转弯灯(EAST2SOUTH,WEST2NORTH)
走完右转路线的灯(SOUTH2EAST,EAST2NORTH,NORHTN2WEST,WEST2SOUTH)
走完右转路线的灯(SOUTH2EAST,EAST2NORTH,NORHTN2WEST,WEST2SOUTH)
-------------------------------------------------------------------------------------------------------------------------
三:代码实现
路线Road类import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Road {
/* 路线上车辆存放的临时缓冲*/
private List<String> vechicles = new ArrayList<String>();
/* 车辆名称描述*/
private String name;
/*某路线存放车辆最大数*/
private int vechiclesMaxNumber;
public Road(String name ,int vechiclesMaxNumber){
this.name = name;
this.vechiclesMaxNumber = vechiclesMaxNumber;
this.generationVechicles();
this.moveVechicles();
}
/**
* 模拟某路线上不断有车辆增加
*/
public void generationVechicles(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
for(int i=1;i<=vechiclesMaxNumber;i++){
try{
/* 随机控制产生车辆的时间间隔*/
Thread.sleep((new Random().nextInt(10)+1)*1000);
/* 将车辆添加到集合 */
vechicles.add(name+"第"+"["+i+"]"+"辆车");
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
});
}
/*
* 每个一秒处理事务,某路线对应的灯是否为绿灯,若是则车辆放行,路线上车辆减少一个
*/
public void moveVechicles(){
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
if(vechicles.size()>0){
/* 判断当前灯状态,若为绿灯,则当前路线的车辆放行*/
if(Lamp.valueOf(name).isLightState())
System.out.println(vechicles.remove(0)+": 已从 "+"["+Lamp.valueOf(name).getRoadName()+"]"+"驶过路口 ");
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
交通灯 Lamp 类
package com.isoftstone.interview.traffic;
/**
*
* 每个枚举元素是一个路线方向的灯
* 每个路线对应的相反路线,此两个合并成一组,一组线路的灯状态一致,即控制每组灯的一个灯
* @author jonn
* @version v1.0
*
*/
public enum Lamp {
/* 直线 路线的交通灯
* 线路相反方向的灯忽略不计
* 第一个参数 当前路线名称描述,第二个参数 指向一组灯中对应相反的路线灯,第三个参数 下一组的路线灯,
* 当前路线灯的状态,true(绿灯),false(红灯)
* */
SOUTH2NORTH("南北方向直线路线","NORTH2SOUTH","SOUTH2WEST",false),
NORTH2SOUTH("北南方向直线路线",null,null,false),
EAST2WEST("东西方向直线路线","WEST2EAST","EAST2SOUTH",false),
WEST2EAST("西东方向直线路线",null,null,false),
/* 左转路线的交通灯
* 线路相反方向的灯忽略不计
* */
SOUTH2WEST("南西方向左转路线","NORTH2EAST","EAST2WEST",false),
NORTH2EAST("北东方向左转路线",null,null,false),
EAST2SOUTH("东南方向左转路线","WEST2NORTH","SOUTH2NORTH",false),
WEST2NORTH("西北方向左转路线",null,null,false),
/* 右转路线的交通灯
* 右拐弯的灯无红绿灯控制,总是绿灯状态
* */
SOUTH2EAST("南东方向右转路线",null,null,true),
EAST2NORTH("东北方向右转路线",null,null,true),
NORTH2WEST("北西方向右转路线",null,null,true),
WEST2SOUTH("西南方向右转路线",null,null,true);
/* 当前路线名称描述*/
private String roadName;
/* 当前路线交通灯状态, 亮(绿灯),暗(红灯)*/
private boolean lightState;
/* 当前路线对应相反的路线的交通灯*/
private String oppositeLight;
/* 当前路线指向下一个路线的交通灯*/
private String nextLight;
private Lamp(String roadName,String oppositeLight,String nextLight,boolean lightState){
this.roadName = roadName;
this.oppositeLight= oppositeLight;
this.nextLight = nextLight;
this.lightState = lightState;
}
/**
* 获取当前灯的状态
* @return
*/
public boolean isLightState(){
return this.lightState;
}
/**
* 当前交通灯为绿,则对应方向的交通灯为绿
*/
public void alight(){
this.lightState = true;
if(oppositeLight!=null){
Lamp.valueOf(oppositeLight).alight();
}
}
/**
* 当前交通灯为红,则对应方向的交通灯为红
* @return next (下一个变为绿的灯 )
*/
public Lamp blackOut(){
this.lightState = false;
if(oppositeLight!=null){
Lamp.valueOf(oppositeLight).blackOut();
}
Lamp next = null;
/* 下一组灯 不为null,则变为绿灯,且返回当前灯*/
if(nextLight!=null){
next = Lamp.valueOf(nextLight);
next.alight();
}
return next;
}
/**
* 返回当前灯的路线描述
* @return
*/
public String getRoadName(){
return this.roadName;
}
}
交通控制类 LampControllel
package com.isoftstone.interview.traffic;
/**
* @author jonn
* @version v1.0
*/
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class LampController {
/* 某条路线当前灯*/
private Lamp currentLight;
public LampController(Lamp currentLight){
this.currentLight = currentLight;
/*当前灯为绿灯*/
currentLight.alight();
this.shceduledLight();
}
/***
* 每隔10秒处理事务,轮流改变所有路线的灯状态,将当前绿灯变为红灯,并将下一个路线方向的灯变为绿灯
*/
public void shceduledLight(){
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
currentLight = currentLight.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
客户端 MainTraffic 类
package com.isoftstone.interview.traffic;
/**
* @author jonn
* @version v1.0
*/
public class MainTraffic {
/*每条路线固定的车辆数量*/
private static int vechiclesNumber = 1000;
/*12条路线的灯*/
private static String[] roads = {
"SOUTH2NORTH","SOUTH2WEST","EAST2WEST","EAST2SOUTH",
"NORTH2SOUTH","NORTH2EAST","WEST2EAST","WEST2NORTH",
"SOUTH2EAST","EAST2NORTH","NORTH2WEST","WEST2SOUTH"
};
/* 每条路线生成与减少车辆*/
public static void generationRoad(){
for(int i=0;i<roads.length;i++){
new Road(roads[i],vechiclesNumber);
}
}
/*生成交通灯控制器,指定南北直线路线为当前灯*/
public static void generationLampController(){
new LampController(Lamp.SOUTH2NORTH);
}
public static void main(String[] args){
generationRoad();
generationLampController();
}
}
运行结果
