第一部分 需求分析
1、 模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
Ø 异步随机生成按照各个路线行驶的车辆
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
Ø 信号灯忽略黄灯,只考虑红灯和绿灯。
Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
2、需求分析
(1)道路对象
在本题中涉及的数据主要是道路的名称,准确的说是道路上车流的方向,可以想象,一个车流方向就是一条路,那么有多少个车流方向就应该有多少条路,而且这些路之间是相互独立的,也就是说每条路上面的方法是按照自己的节奏去实现的,因此我们可以把这些交流流向抽象成多个线程,这个线程的名字就是交通流向的名字,而线程中的方法,就是我们对道路上车辆的方法,这个方法包括了随机增加车辆,控制车辆位置;
(2)交通灯对象
该对象的作用就是控制交通灯的状态,因为交通灯的数量是有限且固定的,而且交通灯是控制交通流向的,也就是和交通流向是绑定的,也就是和道路的名称是同一个对象,所以,我们可以通过一个枚举类定义交通灯,如在规定的时间内让红绿灯交替,并让道路接收这个状态,然后在道路的方法中设置一个判断让道路上的汽车在交通灯为绿色的情况下,每一秒中通过一辆,因为这里涉及到多条线路,而且有些方向上的灯是相同的状态,所以在交通灯这个类里,我们就需要明确有多少路灯,而且把相同状态的灯进行绑定,最后因为灯是交替的,所以需要知道当前状态下,下一个灯或者路线的名字
(3) 基于前面的分析,可以画出如下合理的十字路口交通流示意图,
根据图示,可以列出12条交通流,也就是12条道路,而对于交通灯来说,因为很多灯的状态是联动的,所以实际控制的时候,只需要控制其中的4组灯即可,而灯具有交替性,所以我们必须根据实际的交通状态,在让当前路线的绿灯熄灭时返回下一个路线的绿灯状态;
第二部分 代码实现
1、路线类
根据前面的分析,一共有12条路线,其中每条路线都有两个方法,一个是随机产生车辆,另外一个是定时移动车辆(让车辆通过路口);所以这里可以定义个集合来保存车辆,而车辆的命名则通过灯的名字(前面分析已经说过,路线的名字和灯的名字实质都是同一个对象)加上该路线上出现的车辆个数组合实现,这样既可以区分不同的路线,又可以知道每天路线上产生了多少车,以及当前是那个车通过了路口;为了方便的应用,这里使用了线程池;
submit
Future<?> submit(Runnable task)
- 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。该 Future 的 get 方法在 成功 完成时将会返回 null。
参数:
- 返回:
task
- 要提交的任务- 表示任务等待完成的 Future
抛出:RejectedExecutionException
- 如果任务无法安排执行NullPointerException
- 如果该任务为 nullscheduleAtFixedRate
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
- 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。如果任务的任何一个执行遇到异常,则后续执行都会被取消。否则,只能通过执行程序的取消或终止方法来终止该任务。如果此任务的任何一个执行要花费比其周期更长的时间,则将推迟后续执行,但不会同时执行。
参数:
command
- 要执行的任务initialDelay
- 首次执行的延迟时间period
- 连续执行之间的周期- 返回:
unit
- initialDelay 和 period 参数的时间单位- 表示挂起任务完成的 ScheduledFuture,并且其 get() 方法在取消后将抛出异常
抛出:RejectedExecutionException
- 如果无法安排执行该任务NullPointerException
- 如果 command 为 nullIllegalArgumentException
- 如果 period 小于等于 0
代码:
package com.isimport 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 =null;public Road(String name){this.name = name;//模拟车辆不断随机上路的过程