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

时间:2023-02-17 20:07:05

http://edu.csdn.net/heima android培训http://edu.csdn.net/heima ; java培训期待与您交流!

交通灯管理系统

 

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

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

例如:

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

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

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

       。。。

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

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

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

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

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

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

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

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

面向对象程序设计把握一个重要的经验:谁拥有数据,谁就对外提供操作这些数据的方法。

应用到的其他知识点:

Executors:是jdk1.5后出现的,可以产生线程库。

这个类中有各种静态方法。
       newSingleThreadExecoutor():创建一个使用单个 worker 线程的 Executor。

       newFixedThreadPool(int nThread):创建一个线程库。

Rndom类:此类的实例用于生成伪随机数流。(在系统中主要用于在路上随机生成车辆)。

定时器:就是一个线程池用于定时执行某个任务。参数为定时执行的任务(new Runnable()),第一次执行任务的时间,再次执行任务的时间,时间度量。

Road路面向对象分析:

每条路上都会出现多辆车,路上随机增加新车,在绿灯期间还要没秒减少一辆车。

      设置一个Road类来表示路线,每个Road对象代表一条路线,总共有12条路线,也就是说有12个Road对象。

       每条路上随机增加新的车辆,增加到一个集合中。

       每条路线每隔一秒都会检查控制本路线的灯是否为绿,是,则将保存到集合中的第一辆车移除,即表示穿过了路口。

//该类用于描述交通灯系统中的路

package com.isoftstone.interview.traffie;

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;

//描述路。

publicclass Road {

    //尽量面向接口编程,这样扩展性比较高。

    private List<String>vechicles =new ArrayList<String>();

    private Stringname =null;

    public Road(String name){

       this.name = name;

       //描述路产生车的情况,在随机时间内不断往集合中添加车。

       ExecutorService pool = Executors.newSingleThreadExecutor();//产生随机线程。

       //将一个任务交给线程执行。(相当于Thread t = new Thread(r))

       pool.execute(new Runnable(){

           publicvoid run(){

              for(int i=1;i<1000;i++){

                  try {

                     //让正在执行的线程随机停1到10秒。

                     Thread.sleep((new Random().nextInt(10)+1)*1000); 

                  } catch (InterruptedException e) {

                     e.printStackTrace();

                  }

                  vechicles.add(Road.this.name+"__"+i);

              }

           }

       });

       //返回定时器。用于描述车辆穿过路的情况。(也就是取出车的情况。)

       ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

       //定时器定时执行的任务是Runnable对象的中的run方法。

       timer.scheduleAtFixedRate(new Runnable(){

           @Override

           publicvoid run(){

              if(vechicles.size()>0){//路上是否有车。

                  boolean lighted = Lamp.valueOf(Road.this.name).isLighted();   

                  if(lighted){//是否灯亮。 

                     System.out.println(vechicles.remove(0)+"is traversing !"); //判断都满足,就删除车。

                  }

              }

           }

       },

       1, //过多少秒调用run任务。

       1, //再过多少秒调用run任务。

       TimeUnit.SECONDS);//说明前面两个1的度量单位为秒。

    }

}

Lamp灯的面向对象分析:

每条路线每隔一秒都会检查控制本路线的灯是否为绿,一个灯由绿变红时,应该将下一个灯变绿。

设计一个Lamp类来表示一个交通灯,每个交通灯都维护一个状态:亮(绿)或不亮(红),每个交通灯要有变变绿和变红的方法,并能返回自己的红绿情况。

每个lamp元素代表一个方向上的灯,总共有12个方向,所以总共有12个lamp元素。右拐弯的灯为常绿。

除了右拐弯的方向的其他8条路线的灯,他们是两两成对的,可以归纳为四组,所以在编程时,只要从这4组中各取出一个灯,对这4个灯一次轮着变亮,与这四个灯对应的灯随之变化,因此Lamp类中要有一个变量来记住反方向的灯,在一个Lamp对象的变亮和变黑方法中,将对应方向的灯也变亮或变黑。每一个灯变黑时,都伴随着下一个灯变亮,Lamp类中还用一个变量来记住自己的下一个灯。

无论在程序的什么地方获取某个方向的灯时,每次获得的都是同一对象,所以Lamp类改用枚举来做比较方便。永远都只有代表12个方向的灯的实例。

package com.isoftstone.interview.traffie;

//描述灯。

publicenum 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);

   

    privatebooleanlighted;//true表示亮,falue表示黑。

    private Stringopposite;//代表对应的灯的名字。

    private Stringnext;

    private Lamp(String opposite,String next,boolean lighted){

       this.opposite = opposite;

       this.next = next;

       this.lighted = lighted;

    }   

    //有一个方法返回该灯是亮还是黑。

    publicboolean isLighted(){

       returnlighted;

    }

    //灯变亮方法。

    publicvoid ligth(){

       this.lighted =true;

       if(opposite !=null){

           Lamp.valueOf(opposite).ligth();

       }

       System.out.println(name()+"lamp is green,下面总共应该有6个方向能看到汽车穿过!");//用于调试程序。

    }  

    //将亮的灯变黑,并返回下一个变亮的灯。

    public Lamp blackOut(){

       this.lighted =false;

       if(opposite !=null){

           Lamp.valueOf(opposite).blackOut();

       }

       Lamp nextLamp = null;

       if(next !=null){

           nextLamp = Lamp.valueOf(next);

           System.out.println("绿灯从"+name()+"-------->切换为" + next);

           nextLamp.ligth();

       }

       return nextLamp;

    }

}

 

Lamp灯的控制器分析:  

Lamp灯有12个,除了往右拐弯的4个等长亮,其他8个Lamp灯默认情况是黑的。

设置一个灯控制器,灯控制器开启会默认指定一组灯变亮,在指定时间内再将这组灯变黑,这组灯变黑的同时,会伴随着下一组等变亮。

//描述灯的控制器。

publicclass LampController {

    private LampcurrentLamp;//当前的灯。

    public LampController(){

       currentLamp = Lamp.S2N;

       currentLamp.ligth();

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

       timer.scheduleAtFixedRate(

              new Runnable(){

                  publicvoid run(){

                     currentLamp =currentLamp.blackOut();//10秒后将当前的灯变黑,返回下一个变亮的灯。 

                  }

              },

              10,

              10,

               TimeUnit.SECONDS);

    }

}

 

package com.isoftstone.interview.traffie;

publicclass MainClass {

    publicstaticvoid main(String[] args) {

      

       //创建12个灯对象。

       String[] directions =new String[]{

              "S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"

       };

       //创建12个路对象。

       for(int i=0;i<directions.length;i++){

           new Road("directions[i]");

       }

       //创建控制器。

       new LampController();      

    }

}

 

http://edu.csdn.net/heima android培训 http://edu.csdn.net/heima ; java培训期待与您交流!详细请查看http://edu.csdn.net/heima