黑马程序员——交通灯管理系统

------- android培训java培训、期待与您交流! ----------

 

业务需求

模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:

 

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

例如:

       由南向而来去往北向的车辆 ----直行车辆

       由西向而来去往南向的车辆 ----右转车辆

       由东向而来去往南向的车辆 ----左转车辆

       。。。

 

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

 

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

 

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

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

 

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

 

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

 

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

 

分析

1.      十字路口的每个路口的车行驶的方式都有直行,左转,右转3,所以一共有12条线路,分别是S2N, S2W, E2W, E2S, N2S, N2E, W2E, W2N, S2E, E2N, N2W, W2S

2.      因为一个路口与它相对的路口等灯的信号是一样的,所以这里只需要考虑南边和东边的信号灯,它们对面的灯随着它们的改变就可以

3.      需要的实体有路,,,灯控制器,可以将车存入集合中,将集合装入路的对象中,所以最后一共有三个实体,,,灯控制器

4.      每条路线对应一个灯,四个右转固定是绿灯,其它的每次将一个和它对面变成绿灯,10秒后将灯变红,下个灯及它对面的灯变绿

5.      灯可以用枚举来表示,每个枚举对象指定它对面的灯,下一个灯和当前灯的状态

6.      灯控制器里面定义初始路线,并定义定时器将初始路线的灯变红,下一个变绿,不能定义没有指定对面路口灯和下一个灯的Lamp为初始路线

 

代码示例

1.      Road,里面有添加车辆和移除车辆的两个线程

package com.itcast.trafficschedule;

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 {
	// 创建一个集合, 保存车辆, 车辆用String表示
	List<String> vehicles = new ArrayList<String>();
	// 定义变量保存路的名字
	String name;

	// 定义构造方法接收路的名字并向路中添加车辆
	public Road(String name) {
		this.name = name;

		// 创建线程来给路面添加车辆
		new Thread() {
			public void run() {
				for (int i = 1; i <= 1000; i++) {
					try {
						// 1-10秒内随机添加一辆车
						Thread.sleep((new Random().nextInt(10) + 1) * 1000);
						vehicles.add(Road.this.name + "_" + i);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

		// 创建线程池, 创建线程的第二种方式
		// ExecutorService pool = Executors.newSingleThreadExecutor();
		// //执行线程往集合中添加车辆
		// pool.execute(new Runnable() {
		// public void run() {
		// for (int i = 1; i <= 1000; i++) {
		// try {
		// //1-10秒内随机添加一辆车
		// Thread.sleep((new Random().nextInt(10) + 1) * 1000);
		// vehicles.add(Road.this.name + "_" + i);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		// }
		// });

		// 如果是绿灯, 每隔一秒让路口的第一辆车通过
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		// 按固定频率开启线程的方法, 这里是每隔一秒执行一次
		timer.scheduleAtFixedRate(new Runnable() {
			public void run() {
				if (vehicles.size() > 0) {
					boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
					if (lighted) {
						System.out.println(vehicles.remove(0) + "通过了路口");
					}
				}
			}
		}, 1, 1, TimeUnit.SECONDS);
	}
}


 

2.      Lamp枚举类,里面有12条线路的灯

package com.itcast.trafficschedule;

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);

	// 定义对面的灯的字符串形式
	String opposite;
	// 定义下一个灯的字符串形式
	String next;
	// 定义灯的状态, true为绿灯, false为红灯
	boolean lighted;

	// 构造方法用于初始化灯的状态
	private Lamp(String opposite, String next, boolean lighted) {
		this.opposite = opposite;
		this.next = next;
		this.lighted = lighted;
	}

	// 得到灯的状态
	public boolean isLighted() {
		return lighted;
	}

	// 绿灯亮的方法
	public void light() {
		// 将当前对象的灯变为绿灯
		this.lighted = true;
		System.out.println(name() + "是绿灯, 会有6个方向的车通过");
		// 将它对面的灯变为绿灯
		if (this.opposite != null) {
			Lamp.valueOf(opposite).light();
		}
	}

	// 红灯亮的方法
	public Lamp blackOut() {
		// 将当前灯变红
		this.lighted = false;
		// 将对面的灯变红
		System.out.println(name() + "变成了红灯");
		if (this.opposite != null) {
			Lamp.valueOf(opposite).blackOut();
		}

		//
		Lamp nextLamp = null;
		// 将它的下一个灯变绿
		if (this.next != null) {
			nextLamp = Lamp.valueOf(this.next);
			nextLamp.light();
		}

		return nextLamp;
	}
}


 

3.    灯控制类, 里面定时改变灯的状态

package com.itcast.trafficschedule;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class LampController {
	// 定义当前的灯的对象
	Lamp currentLamp;

	// 构造方法
	public LampController() {
		// 将当前灯先设置为红灯
		currentLamp = Lamp.S2N;
		currentLamp.light();
		// 每隔10秒让下一个灯变绿, 当前变红
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable() {
			public void run() {
				// 将当前灯变成红灯, 下一个灯变绿
				currentLamp = currentLamp.blackOut();
			}
		}, 10, 10, TimeUnit.SECONDS);
	}
}


 

4.    执行程序的主类

package com.itcast.trafficschedule;

public class MianClass {
	public static void main(String[] args) {
		// 创建数组保存12条路线
		String[] directions = { "S2N", "S2W", "E2W", "E2S", "N2S", "N2E",
				"W2E", "W2N", "S2E", "E2N", "N2W", "W2S" };
		// 生成12条线路的对象
		for (int i = 0; i < directions.length; i++) {
			new Road(directions[i]);
		}

		// 创建灯控制器
		new LampController();
	}
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值