------
Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
交通灯管理系统
项目需求:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1、异步随机生成按照各个路线行驶的车辆。
2、信号灯忽略黄灯,只考虑红灯和绿灯。应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
3、具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的逻辑控制。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
4、每辆车通过路口时间为1秒(提示:通过线程Sleep的方式模拟)。
5、随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
6、不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展示程序运行结果。
项目分析:
1、可以只考虑四条线路,横向的直行和左转,纵向的执行和左转。
2、运行逻辑为:东西向直行——东西向左转——南北向直行——南北向左转——继续循环。
3、对象:红绿灯,红绿灯的控制系统,汽车,路。
4、汽车看到绿灯后,还要看前面是否有车,才能开动。想知道前面是否有车,可以问路对象,路中存储着车辆的集合,路上应该有增加和减少车辆的方法。题目中不需要考虑车辆移动的过程,只需要知道车辆穿过路口就行了,所以车辆可以定义为一个字符串。
面向对设计的经验:谁拥有数据,谁就对外提供操作这些数据的方法。
5、设计一个灯类,每个交通灯对象都有两个状态:红、绿,两个方法:变红、变绿,并且能够返回当前状态。
6、总共有12条路线,所以系统中总共要产生12个交通灯,右转虽然不受交通灯控制,但我们可以虚拟4个常亮的交通灯,表示其状态。(可以使用枚举,因为这12个灯的对象不会改变)
7、除去右转弯方法,其他的8条路线的灯都是成对的,所以可以把这8个灯分为四组,操作这四个灯的状态就行了。
8、灯:灯作为一个枚举类,里面除了要有12个实例灯外,还需要有三个变量,一个变量记住自己反方向的灯,使其跟随自己改变状态。一个变量记住下一个方向的灯,在自己变红时,让它变绿。还有一个变量用来保存自身当前状态是红还是绿。
9:控制系统:控制系统中需要有一个变量,记住当前绿的是哪个灯。需要创建一个定时器,时间到时,让当前的绿灯变红,并返回下一个灯。
具体代码:
路类:
package com.traffic;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/***
* 路类
* @author Administrator
*
*/
public class Road {
private List<String> car=new ArrayList<String>();//该集合用于存放车辆
private String name;//存放车辆名称
public Road(String name)
{
this.name=name;
ExecutorService pool=Executors.newSingleThreadExecutor();//创建只有一个线程的线程池
pool.execute(new Runnable() { //创建一个实现Runnavle接口的匿名内部类
@Override
public void run() {
for(int i=1;i<1000;i++)//循环产生车
{
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//生成1-10的随机数,使线程1~10秒产生一辆车
car.add(Road.this.name+"第"+i+"辆车");
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);//定义定时器
timer.scheduleAtFixedRate( //按照一定的频率去触发某个动作
new Runnable(){
public void run() {
if(car.size()>0)//判断路上是否有车
{
boolean ligthrd=Lamp.valueOf(Road.this.name).isLighted();
if(ligthrd)//判断当前车所在的路的灯是否为绿灯
{
String name=car.remove(0);//使一辆车行驶过路口
System.out.println(name+"跑过去了");
}
}
}
},
1, //指定多长时间开始第一次执行
1, //指定每次执行等待时间
TimeUnit.SECONDS);//指定上面两个参数的时间单位为秒
}
}
灯的枚举类:
package com.traffic;
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 opposite;//记录对应的灯
private String next;//记录下一个灯
private Lamp(String opposite,String next,boolean lighted)//为灯指定对应的灯、下一个灯、和灯的状态
{
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
public boolean isLighted()//读取当前交通灯的状态
{
return lighted;
}
public void light()//使灯变为绿灯状态
{
this.lighted=true;
if(opposite!=null)
Lamp.valueOf(opposite).light();//使对应的灯也变为绿灯状态
}
public Lamp blackOut()//使灯变为红灯状态
{
this.lighted=false;
if(opposite!=null){
Lamp.valueOf(opposite).blackOut();//使对应的灯也变为绿灯状态
}
Lamp nextLamp=null;
if(next!=null){
nextLamp=Lamp.valueOf(next);
nextLamp.light();
}
return nextLamp;
}
}
灯的控制器类:
package com.traffic;
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();//让该灯状态变成绿灯
ScheduledExecutorService time=Executors.newScheduledThreadPool(1);
time.scheduleAtFixedRate(
new Runnable() {
public void run() {
currentLamp=currentLamp.blackOut();
}
},
2,
2,
TimeUnit.SECONDS);
}
}
含有主方法的测试类:
package com.traffic;
public class MainClass {
public static void main(String[] args) {
new Road("S2N");
new Road("S2W");
new Road("E2W");
new Road("E2S");
new Road("N2S");
new Road("N2E");
new Road("W2E");
new Road("W2N");
new Road("S2E");
new Road("E2N");
new Road("N2W");
new Road("W2S");
new LampController();
}
}