---------------------- ASP.Net+Android+IOS开发</a>、.Net培训、期待与您交流! ----------------------
需求:
异步随机生成按照各个路线行驶的车辆。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
分析:
NW E
S
路(Road),有十二条不同方向的路线(S2N,N2S,S2W,N2E,E2W,W2E,E2S,W2N,S2E,E2N,N2W,W2S)。
路上有车辆信息(可以通过一个集合来存储)。
灯(Lamp),灯控制路线上的车是否可以通行。十二条路线对应十二盏灯。灯有红绿状态,让一个控制器控制。
控制灯的控制器(LampController),对灯进行控制,让当前绿灯定时变红。
各个类的实现:
路 (Road)
public class Road {
String name;//当前路的名字,对应灯打名字
ExecutorService pool;
ScheduledExecutorService timer;
List vehicles;//存储车辆
public Road(String name){
this.name = name;
this.pool = Executors.newFixedThreadPool(1);
this.timer = Executors.newScheduledThreadPool(1);
this.vehicles = new ArrayList();
vehicleComing();
vehicleGone();
}
/*
* 随机1-10秒在当前路线产生一辆车。
*/
private void vehicleComing(){
pool.execute(
new Runnable(){
@Override
public void run() {
Random random = new Random();
for(int i =1; i<=100; i++){
try {
Thread.sleep((random.nextInt(10)+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vehicles.add(name + "---" + i);
System.out.println(name + "----" + i + "vehicle coming.");
}
}
}
);
}
/*
* 启动定时器,每隔一秒检查当前路对应的灯是否是绿灯
* 如果是绿灯,移走第一辆车。
*/
private void vehicleGone(){
timer.scheduleAtFixedRate(
new Runnable(){
String temp;
@Override
public void run() {
if(Lamp.valueOf(name).isLighting()){
if(vehicles.size() > 0){
temp = (String)vehicles.remove(0);
System.out.println(temp + "vehicle is gone.");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
灯(Lamp)通过枚举实现
public enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),//只有四盏灯有对应的灯和下一个灯。
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
//与当前灯相对应灯,控制器只要控制四盏灯,其它四盏灯在相应灯改变状态(红,绿)时也同时改变
//相对应灯的关系:S2N-N2S,反方向路线的灯。
private String opposite;
private String nextLamp;//下一盏灯,当前灯变红时,盏灯就要变绿
boolean lighting;//红绿标志
private Lamp(){}
private Lamp(String opposite, String nextLamp, boolean lighting){
this.opposite = opposite;
this.nextLamp = nextLamp;
this.lighting = lighting;
}
public boolean isLighting(){
return lighting;
}
/*
* 让灯变绿方法
* 一个灯变绿时,如果有相对应的灯,相对应的灯也要变绿
*/
public void light(){
this.lighting = true;
System.out.println(this.name() + "变绿了!");
if(this.opposite != null){
Lamp.valueOf(this.opposite).light();
}
}
/*
* 灯变红方法
* 一个灯变红,如果有相对应的灯,相对应的灯也要变红。
*/
public Lamp blackOut(){
this.lighting = false;
System.out.println(this.name() + "变红了!");
if(this.opposite != null){
Lamp.valueOf(this.opposite).lighting = false;
System.out.println(Lamp.valueOf(this.opposite).name() + "变红了!");
}
if(this.nextLamp != null){
Lamp.valueOf(this.nextLamp).light();
}
return Lamp.valueOf(this.nextLamp);
}
}
控制灯的控制器(LampController)
public class LampController {
ScheduledExecutorService timer;
Lamp currentLamp;//存储当前绿灯对象,该对象确定包含相对应灯和下一个灯的信息。
public LampController(Lamp lamp) {
this.currentLamp = lamp;
timer = Executors.newScheduledThreadPool(1);
this.currentLamp.light();
changeLamp();
}
/*
* 定时将currentLamp存储的当前绿灯变成红灯。
*/
private void changeLamp() {
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
currentLamp = currentLamp.blackOut();
}
}, 2, 2, TimeUnit.SECONDS);
}
}
测试功能是否完成(TrafficLightsTest)
public class TrafficLightsTest {
public static void main(String[] args) {
String[] directions = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
new LampController(Lamp.S2N);
for(int i=0,end=directions.length-1; i<=end; i++){
new Road(directions[i]);
}
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------