黑马程序员-交通灯管理系统

来源:互联网 发布:网络诈骗如何判刑 编辑:程序博客网 时间:2024/06/14 00:37

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:

 

Ø 异步随机生成按照各个路线行驶的车辆。

例如:

       由南向而来去往北向的车辆 ---- 直行车辆

       由西向而来去往南向的车辆 ---- 右转车辆

       由东向而来去往南向的车辆 ---- 左转车辆

       。。。

 

Ø 信号灯忽略黄灯,只考虑红灯和绿灯。

 

Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

 

Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

 

Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

 

Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

 

Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。


画图进行具体分析:

面向对象的分析与设计:

设计Road对象表示一条路,12个对象表示12条路,每条路线上随机增加的车辆用字符串表示,并存入集合,每条路检查控制本路线的等是否为绿灯,如果是绿灯就移除集合中的第一个元素打印,表示通过。

import java.util.List;import java.util.ArrayList;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> roadList=new ArrayList<String>();private  String name;//每条路线初始化都有自己的名字,以便于下面为本路线的灯状态做判断。Road(String name){this.name=name;}public  void road(){//建立线程池,每一条路都不定时的增加车辆ExecutorService exe=Executors.newFixedThreadPool(1);exe.execute(new Runnable(){public void run(){for(int x=0;x<10;x++){try{Thread.sleep((new Random().nextInt(10)+1)*1000);}catch(Exception e){}roadList.add(name+"-"+x);}}});//定义定时器,如果当前路线的灯为绿的,就以一秒的频率移除集合中的第一个元素,视为车通过。ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);timer.scheduleAtFixedRate(new Runnable(){public void run(){if(roadList.size()>0){boolean lighted=Lamp.valueOf(name).isLighted();if(lighted)System.out.println(roadList.remove(0)+"  is triving");}}}, 1, 1, TimeUnit.SECONDS);}}
设计一个Lamp类表示交通灯,每个等都有自己的一个状态,绿或者红。因为有12条路线,所以有12个交通灯。右转不受灯的控制,但是为了让程序采用统一的处理方式,设定这4个右转的灯常为绿。

除了右转其他方向的8条路线的灯是两两成对的,分为4组,每一个灯都有3个属性,自己所对应的灯,现在的状态,还有自己的下一个灯。只要取出这4组的一个灯依次变亮,就实现灯的交替变化,因为程序无论从什么地方获得某个方向的灯时,每次获得的都是同一个实例对象,所以Lamp设计成枚举更为方便。

public  enum Lamp{//两两对应的灯,分为4组,默认是红的,并且下一个灯都是这4个在循环。s2n("n2s","s2w",false),s2w("n2e","w2e",false),w2e("e2w","w2n",false),w2n("e2s","s2n",false),n2s(null,null,false),n2e(null,null,false),e2w(null,null,false),e2s(null,null,false),//4个右转的灯常绿s2e(null,null,true),w2s(null,null,true),n2w(null,null,true),e2n(null,null,true);private Lamp(String opposite,String nextLamp,boolean lighted){this.opposite=opposite;this.nextLamp=nextLamp;this.lighted=lighted;}private boolean lighted;private String  opposite; private String nextLamp;//判断当前的灯状态public boolean isLighted(){return lighted;}//绿灯方法public void green(){this.lighted=true;if(opposite!=null)//如果有对应的灯,就将他也变绿Lamp.valueOf(opposite).green();System.out.println(name()+"is   green");}//红灯方法,让下一个灯变绿的同时获取当下一个灯的对象。public Lamp red(){this.lighted=false;if(opposite!=null)//有对应的灯,让他也随之变红Lamp.valueOf(opposite).red();Lamp next=null;if(nextLamp!=null){//变红的同时,如果有下一个灯就将他变绿next=Lamp.valueOf(nextLamp);System.out.println("绿灯"+name()+"----->切换为"+nextLamp);next.green();}return next;}}
设计一个灯控制器,它定时当前的绿灯变红。

import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class LampCtrl {private Lamp current;LampCtrl(){//获取第一个灯current=Lamp.s2n;//让第一个灯变绿current.green();//建立定时器,每隔10秒,让当前等变红ScheduledExecutorService  timer=Executors.newScheduledThreadPool(1);timer.scheduleAtFixedRate(new Runnable(){public void run(){//让自己变红同时将下一个对象赋值给自己,依次循环下去current=current.red();}},10,10,TimeUnit.SECONDS);}}
主类里只需建立12条路的对象,调用灯控制器即可

public class Traffic {public static void main(String[] args) {//建立12条路,开启灯控制器String[] str=new String[]{"s2n","s2w","w2e","w2n","n2s","n2e","e2w","e2s","s2e","w2s","n2w","e2n"};for(int x=0;x<str.length;x++ ){new Road(str[x]).road();}new LampCtrl();  }}


 

原创粉丝点击