项目要求:模拟实现十字路口的交通灯管理系统逻辑
具体需求如下: 异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆 。。。
信号灯忽略黄灯,只考虑红灯和绿灯。
应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
通过题意可以了解到本题要三个对象路,车,灯;对于路要处理车上路和过路口功能代码如下
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*
* 因为在十字路口每条路上的有12条,且每条路上都是独立的因此要用到多线程
* 本程序用到了线程池Executors,实现多线程功能
*/
public class Road {
private ArrayList<String> vehicle=new ArrayList<String>();//创建一个集合来模拟路上的车辆
private String roadName;//路的名字啊
public Road(String roadName)
{
this.roadName=roadName;
ExecutorService exec=Executors.newSingleThreadExecutor();//创建一个线程池
exec.execute(new Runnable(){
public void run()
{
for(int i=1;i<=1000;i++)
{
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//模拟十秒内任意时刻出现一辆车
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();//异常没有做处理
}
vehicle.add(Road.this.roadName+"_"+i);//将模拟跑到路上的车装到路上的模拟集合,内部类获得外部类成员变量要加外部类名
}
}
});
ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);//创建一个定时器,实现模拟过马路功能
timer.scheduleAtFixedRate(
new Runnable()
{
public void run()
{
if(vehicle.size()>0){//一开始没有对集合判断数量是多少而引起结果输出不对
boolean lighted=Lamp.valueOf(Road.this.roadName).isLight();//获得的当前路灯状态
if(lighted)//通过路灯状态决定车辆是否通过
System.out.println(vehicle.remove(0)+" is traversing!");
}
}
},
1, //第一次启动时间
1, //期间的时间间隔
TimeUnit.SECONDS//以秒作单位
);
}
}
对于路上的车要受到灯的控制,灯应该实现变红和变绿功能代码如下:
public enum Lamp {
/*
对于S代表的是South,N代表North,W代表West,E代表East,S2N代表由南北的车,其他同理
*/
S2N("S2W","N2S",false),S2W("E2W","N2E",false),E2W("E2S","W2E",false),E2S("S2N","W2N",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 opposite;//当前灯对面的灯的名称
private String nextLamp;//当前灯的下一个灯的名称
private Lamp(String nextLamp,String opposite,boolean lighted)
{
this.opposite=opposite;
this.nextLamp=nextLamp;
this.lighted=lighted;
}
public boolean isLight()//判断灯的状态
{
return this.lighted;
}
public void light()//将灯变绿的方法
{
System.out.println("每次只有六条路可以通车:");
System.out.println(this.name()+"和"+this.opposite+"变绿了");
this.lighted=true;//将当前路上的灯变为绿色
Lamp.valueOf(this.opposite).lighted=true;//将对面的灯也变绿
}
public Lamp black()//将灯变红的方法
{
this.lighted=false;
Lamp.valueOf(this.opposite).lighted=false;
Lamp next=Lamp.valueOf(this.nextLamp);
next.light();//将下一组灯变绿
return next;
}
}
对于灯需要有控制器实现灯的状态转化代码如下:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/*
* 创建一个控制器来实现控制路灯的状态,因为要在一定是时间内改变一次且循环执行所以想到了定时器
*/
public class LampController {
private Lamp lamp;
public LampController()
{
lamp=Lamp.S2N;//初始化灯,就是第一次执行的灯
lamp.light();
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);//实现每隔十秒转化一次灯的状态
timer.scheduleAtFixedRate(
new Runnable(){
public void run()
{
lamp=lamp.black();//将当前的灯变为红灯,并返回下一个灯
}
},
10,
10,
TimeUnit.SECONDS);
}
}
对于上面的题用到java的知识分别是面上对象编程,如果这道题没能正确找到对象之间的关系将很难做出来,当分清对象之间的关系就开始对每一个对象进行分析,先分析路,了解到有十二条路,且他们是相互独立的因此想到应该要用多线程对于实现多线程这里用到了java5中的Executors类线程池来实现的,因为路数是一定的属于想到应该用枚举的方法限定路线,又因为每条路上的是随机出现的所以用到了随机函数,又因为每条路上的车通过路口的时候都为一秒所以应该可以用定时器来完成,对于一定时间内对灯进行改变也用了定时器。
对于灯light方法我没用老师的我觉得直接将他的反方向的灯的状态直接设为true就可以不需要判断,前提是不用递归的方法,用Lamp的valueOf方法实现。
与之相对应的就是black中的灯的状态也用上面的方法。
对于遍历路的时候用增强型for循环就可以实现,因为知识遍历结果,没有对其做其他数据处理,对于这两处改掉后。