交通灯管理系统
---------------------------------------------------------------------------------------------------------------------------------------------
项目名称:
【【【交通灯管理系统】】】
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下
1、 异步随机生成按照各个显露行驶的车辆
1、 异步随机生成按照各个显露行驶的车辆
例如:由南而来去往北的车辆--- 直行车辆由西而来去往南的车辆--- 右转车辆由懂而来去往南的车辆--- 左转这两。。。
2、
信号灯忽略 黄灯,只考虑红灯和绿灯
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4、 具体信号灯控制逻辑与现实生活中的交通灯控制逻辑相同
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制
4、 具体信号灯控制逻辑与现实生活中的交通灯控制逻辑相同
不考虑特殊情况下的控制逻辑注:南北车辆与东南车辆交替放心,同方向等待车辆应放行直行车辆而后放行左转车辆
5、每辆车 通过路口时间为1秒(提示:可通过线程sleep的方式模拟)
6、随机生成车辆时间建个以及 红绿等叫特时间建个自定,可以设置
7、不要求实现GUI, 只考虑系统逻辑实现,可通过LOG方式展现程序运行结果
----
个人感觉
1、找出关键对象2、实现单个对象相关功能3、改进相互间需要的部分功能4、进行测试、调节
----
配图
配图
分析:
1、 该项目涉及到:灯、车、路、控制器。
2、该十字路口,每个方向的车辆会有3种可能的行驶方向,得出合计 有12条路线、同时也是12只灯
3、由此可见,设计到了:红绿灯(题目不要求黄灯)、灯的变频控制器、交通工具、路线。
4、如此:本项目设计到的(对象) 功能类: 1、路线 2、红绿灯、3、控制器 4测试类由于本项目只考虑系统逻辑实现,不要求实现交通工具运行移动的过程,只捕捉交通工具穿过路口的过程同时,交通工具运行到某一条路线上,需要观察该路线上的红绿灯,并且需要知道该自己在路线是否助于第一位置,才能决定是否通过。由此可见,交通工具在本项目中,只是充当路线上的一个元素,1、路线让第一个通过马路(依次),2、路线随机生成后来的交通工具3、本项目有 12条路线
5、灯,逻辑上有12只红绿灯,联系实际生活中,假设右转的4只灯为常绿
并且 直线上的红绿灯会两两对立(这组灯同时变绿灯--另外组则同时变红灯)--与生活中一致了。如此一来,就只剩下4只灯(--对应4只灯--4只常绿灯)在这种设计思维下,编写类的时候,应该初始化:1、对面的灯2、下一个灯3、灯的状态
6、控制器,让灯在规定的时间一到,就变色。应该用一个
变频定时器来完成
1、默认控制一个灯2、变频定时器 定时变灯
7、测试类
1、创建 12条路线2、创建 控制器,开启功能
---
思路
1、class Road 路线
思路
1、class Road 路线
1、路线应该初始化时就指定名称2、路线随机时间add 一辆车
构造函数不能直接创建线程--调用Thread.sleep();1、使用线程池,创建线程池对象2、创建线程
1、设定 随机睡眠时间时间3、移除车辆--通过十字路口2、add 新车
1、需要用线程池对象2、创建一个定时器-按频率移除
1、移除时要进行判断--路线上是否有车1、判断红绿灯的状态--绿灯才移除
2、enum Lamp 红绿灯
1、创建时记得是 enum2、创建12只灯 分三组3、3个关键成员变量:
1、当前等的对面的灯2、当前灯的下一个灯3、当前灯的状态
4、根据成员变量生成相关的方法
1、返回对面灯的方法2、返回下一个灯的方法3、返回当前灯状态的方法4、表示等状态的方法
1、亮状态 >>对应- 绿
1、当前等亮的时候--对面的等同步变亮
2、黑状态 >> 对应- 红1、当前等黑的时候--对面的等同步变黑2、当前等变黑--同步下一组灯 变亮
5、由此得出 构造方法时,需要初始化3个关键元素。
3、class LampContorller 变频控制器
1、默认控制一组灯2、构造方法初始化这只灯为 4组灯的某一个(不能是其他灯)3、构造方法初始化这只灯状态 为 1、亮 2、黑4、继续构建一个变频定时器,进行灯的状态的切换
1、其实很简单,就是设定一个时间 时间-->变黑-->时间-->变亮 无限循环2、记住用Executors 线程池 的对象和方法来完成
4、class MainClass 启动功能测试类
1、new 出12条线路2、new 控制器--> 开启 交通灯测试3、可以把12只灯 放入一个数组--方便new 出12条线路
----------
具体代码:
--
【】交通灯项目-1------Road 路线
【】交通灯项目-2----Lamp 红绿灯
【】交通灯项目-3---------LampController 灯的控制器
【】交通灯项目-4 ------MainClass 测试类
----------
细节问题:
---
1、concurrent 包,对线程和线程池的使用
具体代码:
--
【】交通灯项目-1------Road 路线
public class Road {
//R-1 首先是一个集合 表示每条路线上的车辆
private List<String> vehicles = new ArrayList<String>();
//R-2 每条路 应该有个名字
private String roadName = null;
//R-2-1 通过构造函数,使每创建一条路线的时候,就指定一个名字
public Road(String roadName){
this.roadName = roadName;
//r-3 不能在构造方法中直接Thread.sleep();所以new一个线程池
ExecutorService pool = Executors.newSingleThreadExecutor();
//r-3-1 execute执行 new Runnable 这个内部类
pool.execute(new Runnable(){
@Override//r-3-2 覆盖 run方法
public void run() {
//r-3-2-1 假设每条路上最多999辆车
for(int i=1 ;i<1000 ;i++ ){
try {
//r-3-2-3 随机生成一个1-10的数组*1000 就是秒 在这个时间里后 完成添加
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//r-3-2-2 添加 交通工具 到集合
vehicles.add(Road.this.roadName + "_" + i);
//内部类访问外部类:1 外部类用final 修饰变量 2、重名时候 用类名.this.变量名
}
}
});//command>> Runnable 线程
// pool.execute>>>end
//r-4 定时器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//r-4 定时器 执行一次,或者循环执行:
//timer.schedule(command, delay, unit) 只执行一次 下面这个是按频率执行
//timer.scheduleAtFixedRate(command, initialDelay, period, unit)
//4个参数分别是;任务、循环频率、多久执行一次、前2者的度量单位(秒、分、时等)
timer.scheduleAtFixedRate(
//r-4-1 4个参数分别是:1功能代码、2、1 ,3、1、 4设定前2者为秒
new Runnable(){
@Override// 功能代码:
public void run() {
//r-4-2表示有车辆
if(vehicles.size()>0){
//r-4-3 假如 是绿灯
//boolean lighted = true;
//【】RL-1 Lamp.valueOf(name) 获取到当前路线的灯 并 调用isLighted 判断黑亮状态
boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
if(lighted){
//r-4-4是绿灯就 让第一辆车通行--就是移除 remove 会返回被移除的元素
System.out.println("this car:"+vehicles.remove(0)+"--- is traversing ---");;
}
}
}},
1,
1,
TimeUnit.SECONDS); // end
}
}
//【】RL-1 代表Road 完成并且 Lamp 完成 后
//Road end
【】交通灯项目-2----Lamp 红绿灯
public enum Lamp {
// N
// W E
// S
//L-1 12个枚举值
// S2N,S2W,E2W,E2S,//A 正面 - 主功能
// N2S,N2E,W2E,W2N,//b 对面
// S2E,W2S,N2W,E2N;//c 常绿灯
//[L-14]&&[L-12]&&[L-9]&& [L-1] 12个枚举值
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),//A
//L-2 仅仅是建立枚举值》》S2N
//L-9 仅仅是设定 对面灯》》S2N("N2S")
//L-12 设定灯的 [下一个灯]和 [默认黑亮状态]、》》S2N("N2S","S2W",false)
//[L-14]把所有等都设置完毕--三个参数,右拐常绿
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),//b
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);//c
//L-10 构造方法 获取对面的灯
//L-12 给构造方法添加 下一个灯、默认黑亮参数
//Lamp(String oppsite){ //传递Lamp oppsite 要报错 通过传递String 表示名字来解决
private Lamp(String oppsite,String next,boolean lighted){ //参数:对应灯、下一个灯、默认黑亮状态
this.oppsite = oppsite;
this.next = next;
this.lighted = lighted;
}// L-10、L-12 end
//L-2 交通灯就应该有一个[灯的状态]----表示是亮黑是黑(亮绿,黑红)
private boolean lighted;
//L-6 A [对面的灯] 的名字
private String oppsite;
//L-13 定义[下一个灯]的名字
private String next;
//L-8 判断这个灯的状态 ,是亮黑是黑?
public boolean isLighted(){
return lighted;
}
//L-3 知道是黑是亮后 对面的灯需要同步变化、:
//L-4 亮状态
public void light(){
// this.lighted=true;
//L-7 的A中的灯亮,则对面的灯同步变亮
oppsite.light();
//这里很容易形成死循环,应该通过构造方法设计为,A对应B, B没有对应的,不形成循环。
this.lighted = true;
if(oppsite != null){ //A有对应的灯 才亮, 着时候B 没有对应的,就不会亮
//L-11 构造方法获取到名字以后给枚举,枚举就能返回枚举值对象,再调用亮灯
Lamp.valueOf(oppsite).light();
//oppsite.light();
}
System.out.println("this Lamp "+name() +"------>> to Green 共有6发方向可以通行" );
}
//L-5 黑 状态
public Lamp blackOut(){
this.lighted=false;
//L-15 同//L-7 正面的灯变黑,对面的也变黑。
if(oppsite != null){
Lamp.valueOf(oppsite).blackOut();
}
//L-16 这个灯变黑,则下一个灯 则 变亮--变绿
// if(next != null){
// Lamp.valueOf(next).light();//Lamp end
// }
//LC-1 控制器改进代码
Lamp nextLamp = null ;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("【this Green Lamp :"+name() +"------>> to : " +next+"】");
nextLamp.light();//Lamp end
}
//LC-2 让该方法 在同步变黑的时候,返回下一个灯
return nextLamp;
}
}
//Lamp end
【】交通灯项目-3---------LampController 灯的控制器
public class LampController {
//1、 灯的控制器,肯定要控制一个灯
private Lamp currentLamp;
public LampController(){
//2、初始化当前灯线路、状态
currentLamp = Lamp.S2N;
currentLamp.light();
//3、灯是按照规律来变化的,所以要设计一个 频率定时器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//3-1 4参数 设定频率为10秒,Run功能10运行一次
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
//3-2 应该设计这个灯变黑后,下个等变绿,并且再次调用的时候,是把绿变黑。
//3-3修改 Lamp 类L-16 为:LC-2 currentLamp 具有记忆功能
// blackOut 变黑,并返回下一个灯 所以currentLamp 是下一个的, 这样就循环起来了。
System.out.println("10秒一次来了");
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
//LampController end
【】交通灯项目-4 ------MainClass 测试类
public class MainClass {
public static void main(String[] args) {
//1、new 出12 条路线
//2、new出控制器
//1-1
String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
for(int i=0;i<directions.length;i++){
new Road(directions[i]);
//new Test_R(directions[i]);
}
//模拟交通灯 runing:
new LampController();
}
}//MainClass end
----------
细节问题:
---
1、concurrent 包,对线程和线程池的使用
Executor: 并发 执行已提交的 Runnable 任务的对象 的接口以前没学过,目前了解来说构造方法中不能直接创建线程,通过concurrent 里的对象能够达到相同目的
Executors: 多线程
static ExecutorService newSingleThreadExecutor():
static ExecutorService newFixedThreadPool(int nThreads) :创建单个线程
static ScheduledExecutorService newScheduledThreadPool():创建线程池
ScheduledExecutorService:可安排在给定的延迟后运行或定期执行的命令 的接口创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) :
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)创建并执行在给定延迟后启用的一次性操作。
创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;
TimeUnit unit :是代表long delay或者long initialDelay 的时间单位的 是一个枚举 值是:天、时、分、秒等
2、本项目中细节代码
1、
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.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) {
e.printStackTrace();
}
vehicles.add(Road.this.roadName + "_" + i);
}
}
});
1、拿到线程池的对象2、调用execute 来创建线程3、execute方法的参数 采用内部类完成
1、线程 Runnable必须覆盖 run 方法
1、Thread.sleep((new Random().nextInt(10)+1)*1000); 生成随机睡眠时间2、vehicles.add(Road.this.roadName+ "_" + i); 添加了一个新的交通工具
2、
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run() {
if(vehicles.size()>0){
//boolean lighted = true;
boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
if(lighted){
System.out.println("this car:"+vehicles.remove(0)+"--- is traversing ---");;
}
}
}},
1,
1,
TimeUnit.SECONDS); // end
1、拿到定时器对象2、通过对象 的scheduleAtFixedRate 方法实现 频率定时器3、参数为 线程、频率时、功能运行时、前2者世间单位1、线程 Runnable必须覆盖 run 方法1、判断当前路线的交通工具是否有车1、判断当前等的状态-是黑还是亮1、移除集合第一个元素--达到第一辆车通过十字路口。
3、
public void light(){
this.lighted = true;
if(oppsite != null){
Lamp.valueOf(oppsite).light();
}
System.out.println("this Lamp "+name() +"------>> to Green 共有6发方向可以通行" );
}
1、设定 状态 lighted 为 true 表示亮2、有对面关系,则让对面同亮--枚举设定只有单对面(A>>>>b , b>>>> null)
4、
public Lamp blackOut(){
this.lighted=false;
if(oppsite != null){
Lamp.valueOf(oppsite).blackOut();
}
Lamp nextLamp = null ;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("【this Green Lamp :"+name() +"------>> to : " +next+"】");
nextLamp.light();//Lamp end
}
return nextLamp;
}
1、当前灯为黑--对面等同步为黑2、当前灯为黑--下一组灯同步为亮3、把下一组等提取到判断外
5、
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);
1、12组灯 分三组
1组:主实现功能
1、包含3个参数
1、下一组灯2、对面的灯3、等的状态
2组:1组对面灯3组:常绿灯
6
对应5
1、构造函数进行初始化状态
2、初始化 参数:对面灯、下一个灯、黑亮状态
3、其他需要注意的方法
private Lamp(String oppsite,String next,boolean lighted){
this.oppsite = oppsite;
this.next = next;
this.lighted = lighted;
}
1、构造函数进行初始化状态
2、初始化 参数:对面灯、下一个灯、黑亮状态
3、其他需要注意的方法
Thread.sleep(1000): 线程方法睡眠1000毫秒(new Random().nextInt(10)+1): 随机生成1-10的数字
4、用到的生词
Road: 路
Lamp: 灯
isoftstone: 软通动力 官网
Interview: 面试
traffic: 灯
Vehicles: 交通
execute 执行
lighted 点亮、亮
oppsite 对应的
controller 控制器
current 当前的
direction 方向
light
blackOut
Lamp: 灯
isoftstone: 软通动力 官网
Interview: 面试
traffic: 灯
Vehicles: 交通
execute 执行
lighted 点亮、亮
oppsite 对应的
controller 控制器
current 当前的
direction 方向
light
blackOut
-------
运行结果:
设定的第一个灯是S2N
运行到这里, 已经是一个轮回了。
无限循环执行。
上述代码和上述图片结果有轻微不同。 不影响功能的演示。
---------------------------------------------------------------------------------------------------------------------------------------------
----------
android培训、
java培训 、期待与您交流!----------
----------------------------------------------