ASP.Net+Android+IOS开发.Net培训期待与您交流!
模拟十字路口交通灯管理系统模型,要求如下:
1:异步随机生成按照各个路线行驶的车辆
2:信号灯忽略黄灯,只考虑红灯和绿灯
3:实际逻辑与生活中相同,右转向不受限制
4:每辆车通过路口时间为1秒(可通过线程sleep方法模拟)
5:随机生成车辆时间间隔以及红绿灯交换时间间隔
6:不要求实现GUI,只需实现逻辑即可
看到这个题目,我首先想到的就是我们生活中的交通灯情况,右转向不受信号灯限制,车辆是先直行,后左转弯,东西行驶之后南北再行驶,结合老师所讲的模型,我们可以将12个方向的图简化,只需考虑4条线路即可,即S2N,S2W,E2S,E2W。
然后再仔细分析这个系统有哪些对象,那些类,他们的组合关系是什么?有红绿灯,红绿灯的管理系统,汽车,路。
1:这里,要明白汽车和路的关系,汽车是在路上行驶的,汽车过红绿灯不仅仅看灯是否变绿,还要看前面是否有车,而这又该判断呢?这就要问路,这里,车好比吗咋,路好比一条绳子,在java中,车就好比一个对象,路相当于存储这些对象的集合。这里就需要一点面向对象编程的经验,俗话说谁拥有数据,谁就拥有操作这个数据的方法和属性。车在路上,车是否向前走是由路来决定的,路就拥有增加车减少车的方法。
面向对象编程还可以使用以下例子联系:人在黑板上画圆,火车司机刹车,小明把门关上啦。
2:还需要注意就是灯,12个方向共有十二个灯,这里我们可以用枚举表示各个灯,右转弯为常亮灯,除了4个向右转向的灯,剩下的可以分为4组,因为他们都是两两成对的,所以在编程处理时,只需让这4个灯一次轮训变亮即可,它们相对的灯依次相同变化即可。因此Lamp类中要有一个变量记住相反的灯,在一个Lamp灯变亮或变黑的过程中,将对应方向上的灯也变亮和变黑,每一个灯变亮黑时,都伴随着下一个灯的变黑亮,Lamp类中还有一个变量记录自己下一个灯。
下面来编写路这个类
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.Random;
public class Road {
//把路当成一个装各种车字符串的集合
//面向接口编程,这样让面试官看见比较好
//包名起人家公司的网址比较好,哈哈
private List<String> vechicles = new ArrayList<String>();
//车开到路上来的代码
private String name;
public Road(String name){//传入路的名字
this.name = name;
//生成一个含有一个线程的执行器
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
public void run(){
for(int i=0;i<1000;i++){
try{//线程休眠1到10秒
Thread.sleep((new Random().nextInt(10)+1)*1000);
}catch(InterruptedException e){
e.printStackTrace();
}
//路上加车
vechicles.add(Road.this.name+"_"+i);//访问外部类的成员变量,Road.this.name S2W1代表从南往西的第一辆车
}
}
});
//下面是定时器,每隔一段时间运行一次线程,实际意义为过多长时间走一辆车
// Executors.newScheduledThreadPool(1)new出一个含有一个线程的线程池
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){//以固定频率运行线程
public void run(){
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0)+"is traversing");//返回第一辆车
}
}
}
},
1,//中间间隔为一秒
1,//运行时间为一秒
TimeUnit.SECONDS);//计时单位为妙
}
}
下面是灯这个类
public enum Lamp {
N2S(null,null,false),N2E(null,null,false),S2N("N2S","S2W",false),S2W("N2E","E2W",false),
E2S("W2N","S2N",false),E2W("W2E","E2S",false),W2N(null,null,false),W2E(null,null,false),
N2W(null,null,true),S2E(null,null,true),E2N(null,null,true),W2S(null,null,true);
//与灯同时为绿的相反方向的灯
private String opposite;
//灯是否变绿
private boolean lighted;
//灯变红时下一个变绿的灯
private String next;
public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name()+"lamp is green 下面总共应该看到有6个方向的汽车穿过");
}
public Lamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp = null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从"+name()+"------>切换为"+next);
nextLamp.light();
}
return nextLamp;
}
//对面的灯的状态,灯将要转变的状态,刚开始是否亮
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
private Lamp(){}
//看是否变亮
public boolean isLighted(){
return lighted;
}
}
下面是灯控制器
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
public LampController(){
currentLamp = Lamp.S2N;//设置第一个灯
currentLamp.light();//第一个灯是亮的
//定时器
/*
* 然后启动一个定时器,每隔10秒将当前灯变红和将下一个灯变绿。
* */
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
//这句话记录了当前变绿的灯
currentLamp = currentLamp.blackOut();
}
},
10,//中间间隔10秒
10,//运行时间为10面
TimeUnit.SECONDS);
}
}
测试类
public class MainClass {
public static void main(String[] args) {
String[] dirs = new String[]{
"N2S","N2E","S2N","S2W","E2W","E2S","W2E","W2N","N2W","S2E","E2N","W2S"
};
for(String str:dirs){
//new出每个路,车在不停的上路
new Road(str);
}
//启动红绿灯执行系统
new LampController();
}
}
以上内容解决了三个问题:
1,明白车在路上跑,车字符串,路当作集合,绿灯时车不仅仅看灯,还得看前面是否有车,这就得问路,路有增加车和减少车的方法。
2,12个方向的灯,灯有变亮的方法(同时对面的灯也变亮),灯有变暗的方法(同时返回下一个变绿的灯),还有一个方法显示此时此刻灯是否变亮的状态。
3,定时器,那四个参数,一个是以固定频率运行线程,一个是间隔时间,一个是运行时间,一个是设置单位
线程池,可以设置含有多少个线程运行某个程序,这个是一个线程,隔1到10秒,路上添加一辆车。
ASP.Net+Android+IOS开发.Net培训期待与您交流!