11.继续学习之交通灯管理系统

学习了好多天,总结一下这个项目:

交通灯管理项目模拟了对十字路口交通灯的控制,一般在我们生活中的十字路口是有人行道的,而此项目没有考虑人行道,到下面需求的第3条,右转车辆不受信号灯控制可以看出。

业务需求分析:
1、具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

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

    每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。2、信号灯忽略黄灯,只考虑红灯和绿灯

2、异步随机生成按照各个路线行驶的车辆。由南向而来去往北向的车辆 ---- 直行车辆,,由西向而来去往南向的车辆 ---- 右转车辆, 由东向而来去往南向的车辆 ---- 左转车辆
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4、每辆车通过路口的时间为1秒
5、随机生成车辆的时间间隔,以及红绿灯交换时间间隔自定,可以设置

 

主要代码如下:

 

Road类

  1. import java.util.ArrayList; 
  2.  
  3. import java.util.List; 
  4.  
  5. import java.util.Random; 
  6.  
  7. import java.util.concurrent.ExecutorService; 
  8.  
  9. import java.util.concurrent.Executors; 
  10.  
  11. import java.util.concurrent.ScheduledExecutorService; 
  12.  
  13. import java.util.concurrent.TimeUnit; 
  14.  
  15. public class Road { 
  16.  
  17.     // 保存车辆的集合 
  18.  
  19.     private List<String> vechicles = new ArrayList<String>(); 
  20.  
  21.     // 车辆的名字 
  22.  
  23.     private String name; 
  24.  
  25.     public Road(String name) { 
  26.  
  27.         this.name = name; 
  28.  
  29.         // 在线程池中选择空闲的线程,执行模拟车辆不断随机上路的过程 
  30.  
  31.         Executors.newSingleThreadExecutor().execute( 
  32.  
  33.         new Runnable() { 
  34.  
  35.             @Override 
  36.             public void run() { 
  37.  
  38.                 // 车辆上路是随机的,所以需要一个随机数产生器 
  39.  
  40.                 Random r = new Random(); 
  41.  
  42.                 // 模拟一千辆车上路 
  43.  
  44.                 for (int i = 1; i < 1000; i++) { 
  45.  
  46.                     try
  47.  
  48.                         // 没产生一辆车,线程随机睡眠一段时间 
  49.  
  50.                         Thread.sleep(r.nextInt(11) * 1000); 
  51.  
  52.                     } catch (InterruptedException e) { 
  53.  
  54.                         e.printStackTrace(); 
  55.  
  56.                     } 
  57.  
  58.                     // 把产生的车放进集合中 
  59.  
  60.                     vechicles.add(Road.this.name + "_" + i); 
  61.  
  62.                 } 
  63.  
  64.             } 
  65.  
  66.         }); 
  67.  
  68.         // 获得一个调度线程池 
  69.  
  70.         ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); 
  71.  
  72.         // 执行定时器 
  73.  
  74.         timer.scheduleAtFixedRate( 
  75.  
  76.         // 需要执行的代码 
  77.  
  78.                 new Runnable() { 
  79.  
  80.                     @Override 
  81.                     public void run() { 
  82.  
  83.                         // 路上有车时才执行逻辑 
  84.  
  85.                         if (vechicles.size() > 0) { 
  86.  
  87.                             // 判断与这个类对应的交通灯是否亮着 
  88.  
  89.                             boolean lighted = Lamp.valueOf(Road.this.name) 
  90.                                     .isLighted(); 
  91.  
  92.                             if (lighted) { 
  93.  
  94.                                 // 如果亮着,路前面的车辆就可以走了,也就是把集合中索引为0的代表汽车的String对象移除,并打印出来 
  95.  
  96.                                 System.out.println(vechicles.remove(0)); 
  97.  
  98.                             } 
  99.  
  100.                         } 
  101.  
  102.                     } 
  103.  
  104.                 }, 
  105.  
  106.                 1, // 一秒后启动这个定时器 
  107.  
  108.                 1,// 每隔一秒执行一次 
  109.  
  110.                 TimeUnit.SECONDS);// 时间单位设置为秒 
  111.  
  112.     } 
  113.  

 

 

BankTest主类
 
01./*
02.
03.1、用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。
04.2、再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。
05.
06. */ 
07. 
08.import java.util.concurrent.Executors; 
09.import java.util.concurrent.TimeUnit; 
10. 
11.public class BankTest { 
12.    public static void main(String[] args) { 
13.        // 产生4个普通窗口 
14.        for (int i = 1; i < 5; i++) { 
15.            ServiceWindow window = new ServiceWindow(); 
16.            window.setWindowId(i); 
17.            window.start(); 
18.        } 
19. 
20.        // 产生1个快速窗口 
21.        ServiceWindow expressWindow = new ServiceWindow(); 
22.        expressWindow.setType(CustomerType.EXPRESS); 
23.        expressWindow.start(); 
24. 
25.        // 产生一个VIP窗口 
26.        ServiceWindow vipWindow = new ServiceWindow(); 
27.        vipWindow.setType(CustomerType.VIP); 
28.        vipWindow.start(); 
29. 
30.        // 普通客户拿号 
31.        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { 
32.            public void run() { 
33.                // 创建线程,运行普通客户服务 
34.                Integer serviceNumber = NumberMachine.getInstance() 
35.                        .getCommnManager().generateNewManager(); 
36.                System.out.println("第" + serviceNumber + "号普通客户正在等待服务!"); 
37.            } 
38.        }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS); 
39.        // 快速客户拿号 
40.        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { 
41.            public void run() { 
42.                // 创建线程,运行快速客户服务 
43.                Integer serviceNumber = NumberMachine.getInstance() 
44.                        .getExpressManager().generateNewManager(); 
45.                System.out.println("第" + serviceNumber + "号快速客户正在等待服务!"); 
46.            } 
47.        }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS); 
48.        // VIP客户拿号 
49.        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { 
50.            public void run() { 
51.                // 创建线程,运行VIP客户服务 
52.                Integer serviceNumber = NumberMachine.getInstance() 
53.                        .getVipManager().generateNewManager(); 
54.                System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!"); 
55.            } 
56.        }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS); 
57.    } 
58.} 

 

NumberMachine类
 
01./*
02.
03.1、定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。
04.2、将NumberMachine类设计成单例。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。
05.
06. */ 
07. 
08.//创建号码管理器类 
09.public class NumberMachine { 
10.    // 设计单列 
11.    // 私有构造函数 
12.    private NumberMachine() { 
13.    } 
14. 
15.    private static NumberMachine instance = new NumberMachine(); 
16. 
17.    // 公有静态方法,返回这个单例对象的引用 
18.    public static NumberMachine getInstance() { 
19.        return instance; 
20.    } 
21. 
22.    // 创建三种客户产生号码的机器 
23.    private NumberManager commnManager = new NumberManager(); 
24.    private NumberManager expressManager = new NumberManager(); 
25.    private NumberManager vipManager = new NumberManager(); 
26. 
27.    // 产生get方法,获取对象 
28.    public NumberManager getCommnManager() { 
29.        return commnManager; 
30.    } 
31. 
32.    public NumberManager getExpressManager() { 
33.        return expressManager; 
34.    } 
35. 
36.    public NumberManager getVipManager() { 
37.        return vipManager; 
38.    } 
39.} 

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> vechicles = new ArrayList<String>();

    // 车辆的名字

    private String name;

    public Road(String name) {

        this.name = name;

        // 在线程池中选择空闲的线程,执行模拟车辆不断随机上路的过程

        Executors.newSingleThreadExecutor().execute(

        new Runnable() {

            @Override
            public void run() {

                // 车辆上路是随机的,所以需要一个随机数产生器

                Random r = new Random();

                // 模拟一千辆车上路

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

                    try {

                        // 没产生一辆车,线程随机睡眠一段时间

                        Thread.sleep(r.nextInt(11) * 1000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    // 把产生的车放进集合中

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

                }

            }

        });

        // 获得一个调度线程池

        ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);

        // 执行定时器

        timer.scheduleAtFixedRate(

        // 需要执行的代码

                new Runnable() {

                    @Override
                    public void run() {

                        // 路上有车时才执行逻辑

                        if (vechicles.size() > 0) {

                            // 判断与这个类对应的交通灯是否亮着

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

                            if (lighted) {

                                // 如果亮着,路前面的车辆就可以走了,也就是把集合中索引为0的代表汽车的String对象移除,并打印出来

                                System.out.println(vechicles.remove(0));

                            }

                        }

                    }

                },

                1, // 一秒后启动这个定时器

                1,// 每隔一秒执行一次

                TimeUnit.SECONDS);// 时间单位设置为秒

    }

}

总结: 从这个项目中我又复习了java基础知识, 虽然各个部分学的好 但是你不一定用得好, 合起来就不行了,  还是要多学多练  光知道概念是不行的.  多动手桥代码才是硬道理.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值