黑马程序员—java之交通灯管理系统
------- android培训、java培训、期待与您交流! ----------
人生最大的悲哀不是失去太多,而是计较太多,这也是导致一个人不快乐的重要原因
交通灯管理系统
/*
需求
这个为张老师模拟的十字路口的交通灯(没有黄灯,且右转的车辆无右转交通灯)
具体思维:
1)异步随机生成按照各个路线行驶的车辆。
例如:由南向而来去往北向的车辆...直行车辆。
由西向而来去往南向的车辆...右转车辆。
由东向而来去往南向的车辆...左转车辆。
........
2)信号灯0\4 2 3
忽略黄灯,只考虑红灯和绿灯。
3)应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4)具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5)每辆车通过路口时间为1s。
6)随机生成车辆时时间间隔自定,可以设置。
7)不要求实现GUI,只考虑系统逻辑实现,可通过log方式展现程序运行结果。
系统的没戏与设计
系统中有12条路线,每一条上都会出现多辆车,共有12条路线,需要创建12个对象,没条路上随机产生车辆,把这些车厢保存到一个 集合中。
然后没经过一段时间判断路灯的情况若为绿灯这让车辆通过,也就从路的集合中移出一辆车,表示车辆的通过。
红绿灯
系统中有12条路线,可以模拟出12个路灯,Lamp对象需要改变路灯的状态的方法即红绿灯之间的转换。
代码的实现
public class MainClass {
/**
交通灯信号管理系统
*@param args
*/
publicstatic void main(String[] args) {
/**/
String [] directions = new String[]{
"南向北","南向东","南向西","东向西","东向南","东向北","北向南","北向东","北向西","西向东","西向南","西向北"
};
for(int i=0;i<directions.length;i++){
newRoad(directions[i]);
}
newLampController();
}
}
创建路对象
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 每个Road对象都有一个name成员变量来代表方向,有一个vehicles成员变量来代表方向上的车辆集合。
*在Road对象的构造方法中启动一个线程每隔一个随机的时间向vehicles集合中增加一辆车(用一个“路线名_id”形式的字符串进行表示)。
* 在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。
*
*/
public class Road { //交通工具,代表方向上的车辆集合。
private List<String> vechicles = newArrayList<String>();//创建集合储存车辆
private String name =null;//代表方向
publicRoad(String name){
this.name = name;
//车开到路上的实例对象
ExecutorService pool = Executors.newSingleThreadExecutor();//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
pool.execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){//假设总共有1000辆车
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);//模拟每一秒到十秒增加一个车(用线程休眠方法)
}catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name + "_" + i);//向vehicles集合中增加一辆车
}
}
});
//
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//创建一个定时器,规定一定时间后执行一个任务
timer.scheduleAtFixedRate(//scheduleAtFixedRate(Runnable command, long initialDelay,long period, TimeUnit unit)
newRunnable(){
public void run(){//要执行的任务
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0) + " 通过路口");
}
}
}//在Road对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。
},
1,//首次执行的延迟时间
1,//连续执行之间的周期
TimeUnit.SECONDS);
//来说明签名的数字是代表什么单位(秒 是天))
}
}
/**
创建交通灯对象
1、 系统中有12个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,
综合这些因素,将Lamp类用java5中的枚举形式定义更为简单。
2、 每个Lamp对象中的亮黑状态用lighted变量表示,选用南向北、南向西、东向西、东向北这四
个方向上的Lamp对象依次轮询变亮,Lamp对象中还要有一个oppositeLampName变
量来表示它们相反方向的灯,再用一个nextLampName变量来表示此灯变亮后的下一个变
亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无
法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。
3、 增加让Lamp变亮和变黑的方法:light和blackOut,对于南向北、南向西、东向西、东向北这
四个方向上的Lamp对象,这两个方法内部要让相反方向的灯随之变亮和变黑,blackOut方法还要
让下一个灯变亮。
4、 除了南向北、南向西、东向西、东向北这四个方向上的Lamp对象之外,其他方向上的Lamp对象的
nextLampName和oppositeLampName属性设置为null即可,并且南向北、南向西、东向西、东向北
这四个方向上的Lamp对象的nextLampName和oppositeLampName属性必须设置为null,以便防止light和blackOut进
*
*/
/**/
public enum Lamp {
/*每个枚举元素个表示灯控制的一个方向*/
南向北("北向南","南向西",false),南向西("北向东","东向西",false),
东向西("西向东","东向南",false),东向南("西向北","南向北",false),
/*下面元素表示与上面的元素的相反方向的等,其中所有的参数值不重要应忽略不计!*/
北向南(null,null,false),北向东(null,null,false),
西向东(null,null,false),西向北(null,null,false),
/*有南向东和有西向北不受红绿灯的控制,所以可以假想他们总是绿灯*/
北向西(null,null,true),西向南(null,null,true),
南向东(null,null,true),东向北(null,null,true);
private Lamp(String opposite,Stringnext,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
/*灯是否为绿*/
private boolean lighted;
/*与灯同时为绿的对应方向*/
private String opposite;
/*灯变红时下一个变绿的等*/
private String next;
publicboolean isLighted(){
return lighted;
}
/**
* 灯变绿时,它对应方向的灯也要变绿
*/
publicvoid light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name() + "灯亮绿色下面总共应该有六个方向能看到汽车穿过");
}
/**
*灯变红时 对应方向的灯也要变红,并且下一个方向的灯要变绿
*@return 下一个要变绿的灯
*/
publicLamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}
LampnextLamp= null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.light();
}
return nextLamp;
}
}
import java.util.concurrent.Executors;
importjava.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
publicLampController(){
//刚开始让有南向北的灯变绿
currentLamp = Lamp.南向北;
currentLamp.light();
/*每隔10秒将当前绿灯变成红灯,并让下一个方向的灯变绿*/
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
newRunnable(){
public void run(){
System.out.println("开始切换转向灯");
currentLamp = currentLamp.blackOut();
}
},
10,10,TimeUnit.SECONDS);
}
------- android培训、java培训、期待与您交流! ----------