------ ASP.Net+Android+IO开发.Net培训期待与您交流! ------
总结内容来源于张孝祥老师的7K面试题之交通灯管理系统
看过张老师的交通灯管理系统视频后,明显的感觉到了自己的基础还不够扎实,对于面对对象思想的理解还处于比较低级的层面,总体来说张老师对这套系统的讲解是比较细致,全面的,里面讲了之前没有看过的新知识点,JDK1.5版本中关于线程的新工具类Executors,和里面的定时器.总之这套视频教程不仅让我复习了一些原来学习的基础,又让我学习到了新的知识点,最重要的是对面对对象思想有了更进一步的了解.
交通灯管理系统
系统的需求
1.异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
2. 信号灯忽略黄灯,只考虑红灯和绿灯。
3. 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4.具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5. 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
6. 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7. 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
系统的分析
分析示意图 , 如下
把路线单独定义一个类 ,
#创建线程 , 在路线中持续的产生车辆 , 并存入集合中 ,
#创建线程 , 引入条件 , 当前路线的灯为绿时 , 从集合中移出车辆并打印控制台
2 . Lamp(交通灯)
图中共有12条路线 , 就可以看作为12个固定的交通灯 , 所以就想到了用Enum枚举 ,
由于向右拐弯是不受灯控制的 , 所以4条右转弯的灯一直为绿(true) , 在剩下的8条路线中 , 路线是两两对应的 , S2N-N2S , S2W-N2E ,W2E-E2W , E2S-W2N , 并且第一组灯变红(false)时 , 第二组灯就变绿(true) , 依次往复 , 这样就明确的灯的对应和交替关系 .
3 . LampController(交通灯控制器)
主要控制那个路线的交通灯(Lamp)最先变绿(false) , 然后设置定时器按照固定的时间频率让每条线路变绿(true)变红(false)
下面是代码 :
- package com.study.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.TimeUnit;
- //路线类
- public class Road {
- //创建一个用于存放车辆的集合,可当做为路上行驶的车辆
- private List<String> vehicles = new ArrayList<String>();
- String roadName = null;
- //构造方法传入路的名字,并在该条路上产生车辆,当交通等为绿色时,移出该条路的上的车辆
- Road(String roadName){
- this.roadName = roadName;
- //要记住最关键的Executors(1.5版本后创建线程的新方法),其他自然能够引申出来
- ExecutorService pool = Executors.newSingleThreadExecutor();
- pool.execute(new Runnable(){
- @Override
- public void run() {
- //车的最大数量为1000辆
- for(int i=1; i<1000; i++){
- try {
- //每隔1-10秒,一辆车
- Thread.sleep((new Random().nextInt(10)+1)*1000);
- }
- catch (InterruptedException e) {
- e.printStackTrace();
- }
- //把车放进集合中
- vehicles.add(Road.this.roadName+"_"+i);
- }
- }
- });
- //定义一个计划的线程池,线程的数量为1
- ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
- //创建并执行此线程池,初始可以定时、并且后续具有周期性的方法.
- //用于当交通灯为绿色时,移出当前路上的车辆
- timer.scheduleAtFixedRate(
- new Runnable(){
- @Override
- public void run() {
- if(vehicles.size()!=0){
- boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
- if(lighted){
- System.out.println(vehicles.remove(0)+" is traversing");
- }
- }
- }
- },
- 1,
- 1,
- TimeUnit.SECONDS);
- }
- }
- package com.study.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 Lamp(String opposite,String next,boolean lighted){
- this.opposite = opposite;
- this.next = next;
- this.lighted = lighted;
- }
- private boolean lighted;
- private String opposite;
- private String next;
- //定义一个可以判断灯是绿还是红的方法
- public boolean isLighted(){
- return lighted;
- }
- //灯变绿方法
- public void lightOn(){
- this.lighted = true;
- if(opposite != null){
- Lamp.valueOf(opposite).lightOn();
- }
- System.out.println(this.name()+"变绿");
- }
- //灯变红方法
- public Lamp lightOff(){
- this.lighted = false;
- if(opposite != null){
- Lamp.valueOf(opposite).lightOff();
- }
- System.out.println(next);
- Lamp nextLamp = null;
- if(next != null){
- System.out.println("绿灯由"+name()+"变成"+next);
- nextLamp = Lamp.valueOf(next);
- //System.out.println("test");
- nextLamp.lightOn();
- }
- return nextLamp;
- }
- }
- package com.study.traffic;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.TimeUnit;
- //交通灯控制器
- public class LampController {
- private Lamp currentLamp = null;
- public LampController(){
- currentLamp = Lamp.S2N;
- currentLamp.lightOn();
- //定时器,使灯按照固定的频率循环变绿和变红
- ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
- timer.scheduleAtFixedRate(
- new Runnable(){
- public void run(){
- //把下一个变绿的灯再次赋值给currentLamp
- currentLamp = currentLamp.lightOff();
- }
- },
- 10,
- 10,
- TimeUnit.SECONDS);
- }
- }
- package com.study.traffic;
- //调用类
- public class MainClass {
- public static void main(String[] args) {
- String[] roadNames = new String[]{
- "S2N","S2W","E2W","E2S",
- "N2S","N2E","W2E","W2N",
- "S2E","E2N","N2W","W2S"
- };
- for(String roadName : roadNames){
- new Road(roadName);
- }
- new LampController();
- }
- }