黑马程序员__交通灯

来源:互联网 发布:王珊数据库第五版 编辑:程序博客网 时间:2024/05/16 17:53

------- android培训java培训、期待与您交流!   ---------

需求分析

1.1需求

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

例如:

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

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

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

。。。

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

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

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

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

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

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

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

1.2分析

画图非常有助于理解和分析问题。总共有12条路线,为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的4条路线的控制可以假设称为常绿状态,另外,其他的8条线路是两两成对的,可以归为4组,所以,程序只需考虑图中标注了数字号的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

                             

1.3类的设计

1.3.1Road类的设计:

每条路线内都有一个集合,元素为车辆。绿灯时,每秒减少一辆车;红灯时,随机增加车辆。每条路线每秒都要检查对应的灯是否为绿(亮),是的话即移除集合中的第一辆车,表示汽车通过路口。因为有12条路线,需要有12Road对象。

1.3.2Lamp类的设计:

每个灯在一段时间内只有一个状态:绿或红,每个灯都有变绿或者变红的方法,并且可以返回下一个灯。因为只有2个状态,可以使用布尔值的真假表示:真(绿)、假(红)。因为有12条线路,所有要有12个交通灯。不考虑右转,所以4个右转灯始终是绿灯,车辆可以随时右转。

除了右转,还有8个方向,可以分为4对。

每个需要三个变量,与自己对应的灯,下一个灯,自己的状态

1.3.3LampController类的设计:

需要一个监视器,随时监视本灯的状态,时间一到就将当前的灯变红,并监视下一个灯,循环执行。

 

代码实现

Load

package com.itheima.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;

 

/**

 * 这个类用来表示路

 * 

 * @author mrng

 */

public class Road{

    // 用于存放汽车的集合

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

    // 用来表示每条路的名称

    private String name;

 

    public Road(String name){

        this.name = name;

        // 创建一个线程库

        ExecutorService pool = Executors.newSingleThreadExecutor();

        // 使用一个线程来产生汽车

        pool.execute(new Runnable(){

            public void run() {

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

                    try {

                        // 1-5秒钟之内产生一两汽车

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

                    } catch (InterruptedExceptione) {

                        e.printStackTrace();

                    }

                    // 将汽车添加到集合中

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

                }

            }

        });

 

        /**

         * 定义一个定时器,每隔一秒钟检查灯的状态 

         * 参数解释: 

         * 1,要执行的任务 

         * 2,过多长时间执行 

         * 3,过多长时间再次执行

         * 4,时间模式(这里使用的是秒)

         */

        ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);

        timer.scheduleAtFixedRate(new Runnable(){

            public void run() {

                // 如果是绿灯就放行

                if (Lamp.valueOf(Road.this.name).isGreen()){

                    // 如果集合里有汽车的话执行移除操作

                    if (!vechicles.isEmpty()) {

                        // 将集合里的第一辆车移除,表示通过了路口

                        System.out.println(vechicles.remove(0) + " is traversing");

                    }

                }

            }

        }, 1, 1, TimeUnit.SECONDS);

    }

 

    public List<String>getVechicles() {

        return vechicles;

    }

 

    public void setVechicles(List<String>vechicles) {

        this.vechicles = vechicles;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

}

 


 

Lamp

package com.itheima.traffic;

 

/**

 * 这个类用来表示交通灯

 * 

 * @author mrng

 */

public enum Lamp{

    /**

     * S2N(由南向北,直行),S2W(由南向西,左转),E2W(由东向西,直行),E2S(由东向南,左转),

     * N2S(由北向南,直行),N2E(由北向东,左转),W2E(由西向东,直行),W2N(由西向北,左转),

     * S2E(由南向东,右转),N2W(由北向西,右转),E2N(由东向北,右转),W2S(由西向南,右转);

     */

    S2N("N2S""S2W"false), S2W("N2E""E2W"false), E2W("W2E""E2S"false), E2S("W2N""S2N"false),

    N2S(nullnullfalse), N2E(nullnullfalse), W2E(nullnullfalse), W2N(nullnullfalse),

    S2E(nullnulltrue), N2W(nullnulltrue), E2N(nullnulltrue), W2S(nullnulltrue);

   

    // 与当前灯相反方向的灯

    private String opposite;

    // 当前灯变红时下一个要变绿的灯

    private String next;

    // 当前灯是否为绿灯

    private boolean isGreen;

    // 返回当前灯的状态

    public boolean isGreen() {

        return this.isGreen;

    }

   

    private Lamp() { }

   

    private Lamp(Stringopposite, String next, boolean isGreen){

        this.opposite = opposite;

        this.next = next;

        this.isGreen = isGreen;

    }

   

    // 将当前灯变为绿灯

    public void Changed2Green() {

        this.isGreen = true;

        // 如果当前的灯需要控制相反方向的灯和当前灯的状态一致

        if (this.opposite != null) {

            Lamp.valueOf(opposite).Changed2Green();

            System.out.println("-----" + this.name() + "-------" + opposite + "-----");

        }

    }

   

    // 将当前灯变为红灯

    public Lamp Changed2Red(){

        this.isGreen = false;

        // 如果当前的灯需要控制相反方向的灯和当前灯的状态一致

        if (this.opposite != null) {

            Lamp.valueOf(opposite).Changed2Red();

        }

        // 当前灯变红后,将下一个灯变绿

        Lamp nextLamp = null;

        if (this.next != null) {

            nextLamp = Lamp.valueOf(next);

            nextLamp.Changed2Green();

        }

        // 将下一个要变绿的灯返回给LampController

        return nextLamp;

    }

}


 

LampController 控制器

package com.itheima.traffic;

 

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

 

/**

 * 交通灯的控制器

 * 

 * @author mrng

 */

public class LampController {

    // 当前状态为绿色的灯

    private Lamp currentLamp = Lamp.S2N;

   

    public LampController() {

        //将当前灯变绿

        currentLamp.Changed2Green();

         

        // 10秒钟切换一次灯的状态

        ScheduledExecutorService timer =Executors.newScheduledThreadPool(1);

        timer.scheduleAtFixedRate(new Runnable(){

            public void run() {

                // 将当前灯变红后,得到下一个变绿的灯

                currentLamp = currentLamp.Changed2Red();

            }

        }, 5, 5, TimeUnit.SECONDS);

    }

}


主类

package com.itheima.traffic; /** * 主类 *  * @author mrng */public class MainClass {public static void main(String[] args) {String[] directions = { "S2N", "S2W", "E2W", "E2S",//"N2S", "N2E", "W2E", "W2N",//"S2E", "N2W", "E2N", "W2S" };// 创建12条路线for (String direction : directions) {new Road(direction);} // 开启LampControllernew LampController();}}


 ------- android培训java培训、期待与您交流!   ---------

0 0
原创粉丝点击