黑马程序员--基础复习2012.8.7 交通灯管理系统

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

Road类

l 每个 Road 对象都有一个 name 成员变量来代表方向,有一个 vehicles 成员变量来代表方向上的车辆集合。
l Road 对象的构造方法中启动一个线程每隔一个随机的时间向 vehicles 集合中增加一辆车(用一个“路线名 _id” 形式的字符串进行表示)。
l Road 对象的构造方法中启动一个定时器,每隔一秒检查该方向上的灯是否为绿,是则打印车辆集合和将集合中的第一辆车移除掉。

public class Road {
//路上车辆的集合
List<String> vechicles = new ArrayList<String>();

private String name = null;
//根据路的名字,产生一条路
public Road(String name){
this.name = name;
//创建线程
ExecutorService pool = Executors.newFixedThreadPool(1);

pool.execute(new Runnable() {
@Override
public void run() {
for(int i=1; i<1000; i++){
try {
//休息1~10秒
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//访问外部类的成员变量,增加车辆
vechicles.add(Road.this.name + "_" + i);
}
}
});
//创建定时器线程
ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
//定义定时器
timer.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
//布尔型变量,直接判断
if(lighted){
System.out.println(vechicles.remove(0) + "is traversing");
}
}
}
},//定义定时动作
1,//开始后多少时间单位执行动作
1,//每隔几个单位时间执行动作
TimeUnit.SECONDS);//时间单位
}

}

Lamp类

l 系统中有 12 个方向上的灯,在程序的其他地方要根据灯的名称就可以获得对应的灯的实例对象,综合这些因素,将 Lamp 类用 java5 中的枚举形式定义更为简单。
l 每个 Lamp 对象中的亮黑状态用 lighted 变量表示,选用 S2N S2W E2W E2N 这四个方向上的 Lamp 对象依次轮询变亮, Lamp 对象中还要有一个 oppositeLampName 变量来表示它们相反方向的灯,再用一个 nextLampName 变量来表示此灯变亮后的下一个变亮的灯。这三个变量用构造方法的形式进行赋值,因为枚举元素必须在定义之后引用,所以无法再构造方法中彼此相互引用,所以,相反方向和下一个方向的灯用字符串形式表示。
l 增加让 Lamp 变亮和变黑的方法: light blackOut ,对于 S2N S2W E2W E2N 这四个方向上的 Lamp 对象,这两个方法内部要让相反方向的灯随之变亮和变黑, blackOut 方法还要让下一个灯变亮。
l 除了 S2N S2W E2W E2N 这四个方向上的 Lamp 对象之外,其他方向上的 Lamp 对象的 nextLampName oppositeLampName 属性设置为 null 即可,并且 S2N S2W E2W E2N 这四个方向上的 Lamp 对象的 nextLampName oppositeLampName 属性必须设置为 null ,以便防止 light blackOut 进入死循环。
package cn.lcf.traffic;
/*
 * S2N,S2W,E2W,
 * E2S,N2S,N2E,
 * W2E,W2N,S2E,
 * E2N,N2W,W2S
 */
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),
S4E(null,null,true),E4N(null,null,true),N4W(null,null,true),W4S(null,null,true);//这个用4方便测试辨别
//lighted表示灯的状态
private boolean lighted;
//该等的相反方向的灯
private String opposite;
//下一个灯
private String next;
//灯的构造器,传递反方向名,下一个灯名字,和当前灯状态
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
//空参数构造方法
private Lamp(){

}
//获取灯的状态
public boolean isLighted() {
return lighted;
}
//灯开启
public void light(){

this.lighted = true;
//反方向的灯也同时开启
if(opposite!=null)
Lamp.valueOf(opposite).light();
System.out.println(name() + " lamp is green,下面有六个方向汽车通过");
}
//灯熄灭
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("绿灯从" + name() +"转换为"  +nextLamp.name());
//下一个灯亮起
nextLamp.light();
}
//返回下一个的灯
return nextLamp;
}
}

l 整个系统中只能有一套交通灯控制系统,所以, LampController 类最好是设计成单例。
l LampController 构造方法中要设定第一个为绿的灯。
l LampController 对象的 start 方法中将当前灯变绿,然后启动一个定时器,每隔 10 秒将当前灯变红和将下一个灯变绿。
public class LampController {
private Lamp currentLamp;


private static LampController instance = new LampController();

public static LampController getInstance(){
return instance;
}

private LampController() {
// 定义最初始时的灯
currentLamp = Lamp.S2N;
currentLamp.light();


ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);


timer.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
//将当前灯熄灭,并将当前灯置为下一个灯。
currentLamp = currentLamp.blackOut();
}
}, 
10, 
10, 
TimeUnit.SECONDS);
}
}



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

----------------------详细请查看:http://edu.csdn.net/heima

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值