用观察者模式设计一个交通信号灯调度系统
2014-04-20 19:12
387 查看
这是本人在CSDN上的第一篇博客,写一篇有关于Java中设计模式,多线程调度的一个Demo吧,本人水平有限,望各位博友批评指正。此Demo实现了现实交通信号灯调度车辆通行的功能,为了方便大家理解,省去了黄色信号灯。
最近看了一些Java中的设计模式,比如最简单的单例模式,抽象工厂模式,观察者模式等。在学习了这些设计模式之后,我又对之前写过的一些程序做了改进,本文贴一个交通信号灯的系统,废话不多说,先看一种没有用观察者模式的实现(这种实现来源于传智播客的张孝祥老师的Java多线程课程中的一道面试题,有兴趣的博友可以查看点击打开链接)。
在附代码前先看一下需求吧:
Ø 异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
Ø 信号灯忽略黄灯,只考虑红灯和绿灯。
Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
源代码:
Lamp.java
LampController.java
Road.java
Main.java
下面是使用观察者模式的方法:
Lamp.java
LampController.java
Road.java
Main.java
最近看了一些Java中的设计模式,比如最简单的单例模式,抽象工厂模式,观察者模式等。在学习了这些设计模式之后,我又对之前写过的一些程序做了改进,本文贴一个交通信号灯的系统,废话不多说,先看一种没有用观察者模式的实现(这种实现来源于传智播客的张孝祥老师的Java多线程课程中的一道面试题,有兴趣的博友可以查看点击打开链接)。
在附代码前先看一下需求吧:
Ø 异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
Ø 信号灯忽略黄灯,只考虑红灯和绿灯。
Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
源代码:
Lamp.java
public enum 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); private Lamp(String opposite, String next, boolean lighted) { this.opposite = opposite; this.next = next; this.lighted = lighted; } private String opposite; private String next; private boolean lighted; public boolean isLighted() { return lighted; } public void light() { this.lighted = true; if (opposite != null) { Lamp.valueOf(opposite).light(); } System.out.println(name() + "方向的灯变绿了,下面将有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(next + "方向的灯由红变绿了!"); nextLamp.light(); } return nextLamp; } }
LampController.java
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class LampController { private Lamp currentLamp; public LampController(Lamp lamp) { currentLamp = lamp; currentLamp.light(); ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate(new Runnable() { @Override public void run() { currentLamp = currentLamp.blackOut(); } }, 10, 10, TimeUnit.SECONDS); } }
Road.java
import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Road { private String name;// 路名 private List<String> vehicles = new ArrayList<String>();//车辆集合 public Road(String name) { this.name = name; ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.schedule(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { try { Thread.sleep((new Random().nextInt(10) + 1) * 1000); } catch (InterruptedException e) { e.printStackTrace(); } vehicles.add("" + i); } } }, 0, TimeUnit.SECONDS); ScheduledExecutorService timer2 = Executors.newScheduledThreadPool(1); timer2.scheduleAtFixedRate(new Runnable() { @Override public void run() { if (vehicles.size() > 0) { boolean lighted = Lamp.valueOf(Road.this.name).isLighted(); if (lighted) { String current = vehicles.remove(0); System.out.println(Road.this.name + "路的当前第" + current + "号正在通过路口!"); } } } }, 1, 1, TimeUnit.SECONDS); } }
Main.java
public class Main { public static void main(String[] args) { String[] directions = new String[] { "S2N", "S2W", "E2W", "E2S", "N2S", "N2E", "W2E", "W2N", "S2E", "E2N", "N2W", "W2S" }; for (int i = 0; i < directions.length; i++) { new Road(directions[i]); } new LampController(Lamp.S2N); } }
下面是使用观察者模式的方法:
Lamp.java
import java.util.Observable; public class Lamp extends Observable { public Lamp(boolean lighted, String name) { this.lighted = lighted; this.name = name; } private Lamp opposite; private Lamp next; private boolean lighted; private String name; public String getName() { return name; } public void setNext(Lamp next) { this.next = next; } public void setOpposite(Lamp opposite) { this.opposite = opposite; } public boolean isLighted() { return lighted; } public void light() { this.lighted = true; System.out.println(this.name + "方向的灯变绿了!"); if (opposite != null) { opposite.light(); } // System.out.println(name+"方向的灯正在发送通知....."); // 下面两行通知观察者,此方向的路灯已变绿 setChanged(); notifyObservers(Boolean.TRUE); } public Lamp blackOut() { /* 下面将当前路的灯变红 */ this.lighted = false; System.out.println(name + "方向的灯将要变红了!"); if (opposite != null) { opposite.blackOut(); } // 下面两行通知观察者,此方向的路灯已变红 setChanged(); notifyObservers(Boolean.FALSE); /* 下面将下面一条路的灯变绿 */ Lamp nextLamp = null; if (next != null) { nextLamp = next; nextLamp.light(); } return nextLamp; } }
LampController.java
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class LampController { private Lamp currentLamp; public LampController() { Lamp S2N = new Lamp(false, "S2N"); Lamp S2W = new Lamp(false, "S2W"); Lamp E2W = new Lamp(false, "E2W"); Lamp E2S = new Lamp(false, "E2S"); Lamp N2S = new Lamp(false, "N2S"); Lamp N2E = new Lamp(false, "N2E"); Lamp W2E = new Lamp(false, "W2E"); Lamp W2N = new Lamp(false, "W2N"); Lamp S2E = new Lamp(true, "S2E"); Lamp E2N = new Lamp(true, "E2N"); Lamp N2W = new Lamp(true, "N2W"); Lamp W2S = new Lamp(true, "W2S"); S2N.setNext(S2W); S2W.setNext(E2W); E2W.setNext(E2S); E2S.setNext(S2N); S2N.setOpposite(N2S); S2W.setOpposite(N2E); E2W.setOpposite(W2E); E2S.setOpposite(W2N); Lamp[] lamps = new Lamp[] { S2N, S2W, E2W, E2S, N2S, N2E, W2E, W2N, S2E, E2N, N2W, W2S }; for (int i = 0; i < lamps.length; i++) { new Road(lamps[i]); if (lamps[i].isLighted()) { lamps[i].light(); } } currentLamp = S2N; currentLamp.light(); } public void start() { ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.scheduleAtFixedRate(new Runnable() { @Override public void run() { currentLamp = currentLamp.blackOut(); } }, 10, 10, TimeUnit.SECONDS); } }
Road.java
import java.util.LinkedList; import java.util.Observable; import java.util.Observer; import java.util.Queue; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Road implements Observer { private String name;// 路名 private Queue<String> vehicles = new LinkedList<String>();// 车辆集合 private Timer timer2 = null; public Road(Lamp lamp) { lamp.addObserver(this);// 注册一个观察者 this.name = lamp.getName(); ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); timer.schedule(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { try { Thread.sleep((new Random().nextInt(10) + 1) * 1000); } catch (InterruptedException e) { e.printStackTrace(); } vehicles.offer("" + i); } } }, 0, TimeUnit.SECONDS); } @Override public void update(Observable o, Object arg) { if (arg == Boolean.TRUE) {// 绿灯亮了 System.out.println(name + "方向已经开始放行车辆通过!"); timer2 = new Timer(); timer2.schedule(new TimerTask() { @Override public void run() { if (vehicles.size() > 0) { String current = vehicles.poll(); System.out.println(Road.this.name + "路的当前第" + current + "号正在通过路口!"); } } }, 1000, 1000); } else {// 红灯亮了 timer2.cancel(); System.out.println(name + "方向已停止车辆通行!"); } } }
Main.java
public class Main { public static void main(String[] args) { new LampController().start(); } }
相关文章推荐
- ios观察者设计模式。(在一个类监听另一个类属性的变化时响应)
- 监听器和 利 用观察者设计模式设计一个程序
- 五分钟一个设计模式之观察者模式
- 一天一个设计模式(3):观察者模式
- 监听器和 利 用观察者设计模式设计一个程序
- 一天一个设计模式---观察者模式
- 每天一个设计模式(2):观察者模式
- 每天一个设计模式: 观察者模式(Observer)
- 一个故事一个设计模式之观察者模式
- JTABLE 一个小格子添加2个按钮实现国际化 使用观察者设计模式
- 一天一个设计模式之观察者模式
- 游戏系统设计开发之观察者模式
- 每天一个设计模式之观察者模式
- java常用类库续3(比较器Comparable、Comparator、观察者设计模式、正则表达式、定时调度)
- 最近重构一个通讯系统 想了一个很有趣的设计模式,我就叫——移花接木
- 设计模式在一个系统架构设计中的应用
- 【一个批量计算的调度系统的设计与实现】如果需要对成千上万的网络抓包数据文件在规定的时间内进行解析,应该怎么做?
- 银行业务调度系统_改进 与 模板方法设计模式 共享设计模式
- Java高新技术之银行业务调度系统(java单例设计模式、java枚举)
- 设计模式: 自己手动实现一个观察者设计模式