黑马程序员——java基础学习(交通灯管理系统)

---------------------- ASP.Net+Android+IOS开发</a>、.Net培训、期待与您交流! ----------------------

需求:

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

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

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

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

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

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

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

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


分析:

                                     N
                            W               E
                                     S


     路(Road),有十二条不同方向的路线(S2N,N2S,S2W,N2E,E2W,W2E,E2S,W2N,S2E,E2N,N2W,W2S)。

          路上有车辆信息(可以通过一个集合来存储)。

     灯(Lamp),灯控制路线上的车是否可以通行。十二条路线对应十二盏灯。灯有红绿状态,让一个控制器控制。

    控制灯的控制器(LampController),对灯进行控制,让当前绿灯定时变红。

各个类的实现:

     路 (Road)

public class Road {
	String name;//当前路的名字,对应灯打名字
	ExecutorService pool;
	ScheduledExecutorService timer;
	List vehicles;//存储车辆
	
	public Road(String name){
		this.name = name;
		this.pool = Executors.newFixedThreadPool(1);
		this.timer = Executors.newScheduledThreadPool(1);
		this.vehicles = new ArrayList();
		
		vehicleComing();
		vehicleGone();
	}
	/*
	 * 随机1-10秒在当前路线产生一辆车。
	 */
	private void vehicleComing(){
		pool.execute(
				new Runnable(){
					@Override
					public void run() {
						Random random = new Random();
						for(int i =1; i<=100; i++){
							try {
								Thread.sleep((random.nextInt(10)+1)*1000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							vehicles.add(name + "---" + i);
							System.out.println(name + "----" + i + "vehicle coming.");
						}
					}
				}
				);
	}
	/*
	 * 启动定时器,每隔一秒检查当前路对应的灯是否是绿灯
	 *   如果是绿灯,移走第一辆车。
	 */
	private void vehicleGone(){
		timer.scheduleAtFixedRate(
				new Runnable(){
					String temp;
					@Override
					public void run() {
						if(Lamp.valueOf(name).isLighting()){
							if(vehicles.size() > 0){
								temp = (String)vehicles.remove(0);
								System.out.println(temp + "vehicle is gone.");
							}
						}
					}
				}, 
				1, 
				1, 
				TimeUnit.SECONDS);
	}
}

     灯(Lamp)通过枚举实现

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);
	
	//与当前灯相对应灯,控制器只要控制四盏灯,其它四盏灯在相应灯改变状态(红,绿)时也同时改变
	//相对应灯的关系:S2N-N2S,反方向路线的灯。
	private String opposite;
	private String nextLamp;//下一盏灯,当前灯变红时,盏灯就要变绿
	boolean lighting;//红绿标志
	
	private Lamp(){}
	private Lamp(String opposite, String nextLamp, boolean lighting){
		this.opposite = opposite;
		this.nextLamp = nextLamp;
		this.lighting = lighting;
	}
	public boolean isLighting(){
		return lighting;
	}
	/*
	 * 让灯变绿方法
	 *   一个灯变绿时,如果有相对应的灯,相对应的灯也要变绿
	 */
	public void light(){
		this.lighting = true;
		System.out.println(this.name() + "变绿了!");
		if(this.opposite != null){
			Lamp.valueOf(this.opposite).light();
		}
	}
	 /*
	 * 灯变红方法
	 *   一个灯变红,如果有相对应的灯,相对应的灯也要变红。
	 */
	public Lamp blackOut(){
		this.lighting = false;
		System.out.println(this.name() + "变红了!");
		if(this.opposite != null){
			Lamp.valueOf(this.opposite).lighting = false;
			System.out.println(Lamp.valueOf(this.opposite).name() + "变红了!");
		}
		if(this.nextLamp != null){
			Lamp.valueOf(this.nextLamp).light();
		}
		return Lamp.valueOf(this.nextLamp);
	}
}

控制灯的控制器(LampController)

public class LampController {

	ScheduledExecutorService timer;
	Lamp currentLamp;//存储当前绿灯对象,该对象确定包含相对应灯和下一个灯的信息。

	public LampController(Lamp lamp) {
		this.currentLamp = lamp;
		timer = Executors.newScheduledThreadPool(1);
		this.currentLamp.light();
		changeLamp();
	}

	/*
	 * 定时将currentLamp存储的当前绿灯变成红灯。
	 */
	private void changeLamp() {
		timer.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				currentLamp = currentLamp.blackOut();
			}
		}, 2, 2, TimeUnit.SECONDS);
	}
}

测试功能是否完成(TrafficLightsTest)

public class TrafficLightsTest {

	public static void main(String[] args) {
		String[] directions = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
		
		new LampController(Lamp.S2N);
		for(int i=0,end=directions.length-1; i<=end; i++){
			new Road(directions[i]);
		}
	}
}


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值