交通灯管理系统
1. 模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆---- 直行车辆
由西向而来去往南向的车辆---- 右转车辆
由东向而来去往南向的车辆---- 左转车辆
......
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注意:
1)南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
2)每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
3)随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
4)不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
2. 面向对象的分析与设计
行车路线图:
涉及到的对象:红绿灯、红绿灯控制系统、汽车和公路。
分析:
路拥有车辆这个数据,路本身知道自己身上有几辆车,所以,路上有一个集合,用于存储汽车的,根据谁拥有数据,方法就定义在谁上面,所以路上有增加和删除对象(车)的方法,这样就可以将车和路线绑定在一起。每条路线每隔一秒都会对控制本路线的灯进行判断是否为绿,如果为绿灯就将排在前面的车移走,表示车已经开走。然后设计一个灯的类,里面来设计者12个灯,实际上只需设计四个方向的灯即可,其他的都是对应的。注意把右拐弯的灯设计为常绿。自己的灯绿或黑时,也让自己对立的那一面变绿或黑。当一个灯变黑是让下一个灯变绿。
3. 功能代码的实现
1 路的编写
代码实现如下:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Load {
List<String> vechile=newArrayList<String>();
private String name;
Load(String name)
{
this.name=name;
ScheduledExecutorService time =Executors.newScheduledThreadPool(1);
time.execute(new Runnable(){
@Override
public voidrun() {
for(inti=1;i<1000;i++)
{
try{
Thread.sleep((newRandom().nextInt(10))*1000);//随机的向公 路上开车。
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
vechile.add(i+"::::"+Load.this.name);//把车添加到集合中
//System.out.println("第"+i+"车来了");
}
}
});
ScheduledExecutorService times2 =Executors.newScheduledThreadPool(1);
times2.scheduleAtFixedRate(
new Runnable(){
@Override
publicvoid run() {
//TODO Auto-generated method stub
if(vechile.size()>0) //判断公路上有没有车
{
booleanfight=Lamp.valueOf(Load.this.name).isLigth();
if(fight) //判断是否是绿,如果是把最前面的车移走
{
System.out.println("第"+vechile.remove(0)+"走了!");
}
}
}
},
1, //每隔一秒来运行一下这个程序,查看一下是否有车是否是绿灯
1,
TimeUnit.SECONDS);
}
}
2 .灯的编写
代码如下:
package daiwenjuan.traffic.interview;
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); //利用枚举的方式列出了各个方向的灯。
private boolean lighted;
private String oppsited;
private String next;
Lamp(Stringoppsited,String next,boolean lighted)
{
this.oppsited=oppsited;
this.next=next;
this.lighted=lighted;
}
public boolean isLigth() //用于判断灯是否亮
{
return lighted;
}
public void Lighted()
{
this.lighted=true;
if(oppsited!=null)
Lamp.valueOf(oppsited).Ligthed(); //让与自己相反的灯也变量。
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
}
public Lamp Locked()
{
this.lighted=false;
if(oppsited!=null)
Lamp.valueOf(oppsited).Locked();//让自己相反的灯变黑
Lamp nextLamp=null;
if(next!=null){
nextLamp= Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.Lighted(); //让下一个灯变亮
}
return nextLamp ;
}
}
3 灯的管理器的编写
import java.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LightContruct {
privateLamp light;
LightContruct()
{
light=Lamp.S2N;
light.Lighted();
ScheduledExecutorServicetime = Executors.newScheduledThreadPool(1);
time.scheduleAtFixedRate(
newRunnable(){
@Override
publicvoid run() {
//TODO Auto-generated method stub
light=light.Locked();
//System.out.println(light.name()+"绿了");
}
},
10,
10,//每隔十秒让灯变换一次。
TimeUnit.SECONDS);
}
}
下面是一个测试类:
package daiwenjuan.traffic.interview;
public class testDemo {
/**
* @param args
*/
public static void main(String[] args) {
String[] s={"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
for(int i=0;i<s.length;i++)
{
new Load(s[i]);
}
new LightContruct();
}
}
运行结果:
总结:从这个系统中所学到的知识:一个重要的思想:谁拥有数据,就拥有操作这个数据的方法。在进行分析时,因为车在路上跑,所以不用专门用于定义一个车的类,因为路拥有车的对象,所以在路上操作即可。分析灯时,因为灯都是相对的,所以只操作一半即可,因为每个灯都是唯一的所以想到的枚举。操作等变换时只需定义一个线程池即可。