A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© fantacyleo 金牌黑马   /  2014-8-12 13:50  /  2908 人查看  /  12 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

在张老师讲解的基础上做了一些改动,供大家参考,欢迎批评指正:
1. 为车辆单独写一个类:Vehicle。
        张老师的视频中,车辆只是一个字符串,因此没有专门建一个类。我考虑到车辆编号、行驶方向应该是车辆本身的属性,且为今后做其他扩展方便,故将车辆封装为对象。
2. 简化交通灯类:TrafficLamp
        张老师的视频中,为每个方向都设置了一盏灯。我觉得可以简化,尤其是右转灯仅仅为统一程序逻辑而设计出来,每个路口都放一盏没有必要。从南往北路线的灯变绿(红)时,从北往南路线的灯也是绿(红)的,故可以合并为一盏。同理,从南往西和从北往东的两盏左转灯也可以合并为一盏。最终只需要5盏灯:南北直行灯、南北左转灯、东西直行灯、东西左转灯、右转灯。枚举定义如下:
  1. public enum TrafficLamp {
  2.         // 南北直行灯、南北左转灯、东西直行灯、东西左转灯、右转灯
  3.         SNSTRAIGHT(false, "SNLEFT"), SNLEFT(false, "EWSTRAIGHT"),
  4.         EWSTRAIGHT(false, "EWLEFT"), EWLEFT(false, "SNSTRAIGHT"),
  5.         RIGHT(true, null);
  6.        
  7.         private volatile boolean passable; // 当前灯是否可通行
  8.         private String next; // 下一盏灯. 由于初始化顺序,无法直接获取未初始化的TrafficLamp对象,因而暂时用string
  9.        
  10.         private TrafficLamp(boolean passable, String next) {
  11.                 this.passable = passable;
  12.                 this.next = next;
  13.         }
  14.        
  15.         public boolean isPassable() {
  16.                 return passable;
  17.         }
  18.        
  19.         /**
  20.          * 切换为绿灯
  21.          */
  22.         public void setPassable() {
  23.                 this.passable = true;
  24.                 System.out.println(this + " turn green");
  25.         }

  26.         /**
  27.          * 切换为红灯,同时下一盏灯切换为绿灯
  28.          */
  29.         public TrafficLamp setImpassable() {
  30.                 if (this == TrafficLamp.RIGHT) // 右转灯永不切换
  31.                         return this;
  32.                 this.passable = false;
  33.                 System.out.println(this + " turn red");
  34.                 TrafficLamp nextLamp = TrafficLamp.valueOf(this.next);
  35.                 nextLamp.setPassable();
  36.                 return nextLamp;
  37.         }
  38. }
复制代码

3. 通行线路仍为12条,但作为程序执行入口的TrafficSimulation类的main方法中,只创建启动东西南北4个路口线程,每个路口的直行、左转、右转通行线程由路口类Road负责创建和启动。Road类负责路口车辆生成和车辆通行任务。为每一个车辆通行方向设置一个车辆队列,数据结构为BlockingQueue
  1. /** 直行车队列 */
  2.         private BlockingQueue<Vehicle> straightVehicles = new LinkedBlockingQueue<Vehicle>();
  3.         /** 左行车队列 */
  4.         private BlockingQueue<Vehicle> leftVehicles = new LinkedBlockingQueue<Vehicle>();
  5.         /** 右行车队列 */
  6.         private BlockingQueue<Vehicle> rightVehicles = new LinkedBlockingQueue<Vehicle>();
复制代码

由于每个路口有三个通行方向,因此生成车辆时要随机产生行驶方向,这可以用随机数来完成。生成0、1、2三个随机数,分别代表左转、右转、直行三个方向。
  1. // 随机生成车辆行驶方向,并放入相应车辆队列
  2. int direction = rand.nextInt(3);
  3.         switch (direction) {
  4.                 case 0:
  5.                         leftVehicles.put(new Vehicle(Direction.valueOf("LEFT")));
  6.                         break;
  7.                 case 1:
  8.                         rightVehicles.put(new Vehicle(Direction.valueOf("RIGHT")));
  9.                         break;
  10.                 case 2:
  11.                         straightVehicles.put(new Vehicle(Direction.valueOf("STRAIGHT")));
  12.                         break;
  13.         }
复制代码

全部代码在附件中,可直接在eclipse中导入工程。
P.S. 我的eclipse的文件编码是UTF-8 如果中文注释出现乱码,可参考此信息
7k_交通灯.zip (14.97 KB, 下载次数: 552)

评分

参与人数 1技术分 +1 收起 理由
格子、 + 1 很给力!

查看全部评分

12 个回复

倒序浏览
学习了    阻塞队列比list感觉真实
回复 使用道具 举报
学习了,研究下
回复 使用道具 举报
楼主很厉害
回复 使用道具 举报
很厉害的样子
回复 使用道具 举报
确实啊,当时我看这个视频的时候也在想,这个车可以封装下。
回复 使用道具 举报
楼主大牛,给力。
回复 使用道具 举报
看着很厉害                                                     
回复 使用道具 举报
谢谢分享。
回复 使用道具 举报
赞一个!!!
回复 使用道具 举报
正好到这了, 学习了.
回复 使用道具 举报
有自己的思想 不错,赞一个
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马