您的位置:首页 > 职场人生

黑马程序员技术博客之交通灯问题学习笔记

2014-02-28 10:55 239 查看
----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

以下是我学习张老师交通灯面试题的学习笔记,具体内容参见张老师的博客:联想利泰的一道做出来就给月薪7K的面试题--交通灯管理系统,个人觉得看这篇博客要比看视频省时间。

交通灯问题:模拟一个交通灯管理系统,不要求GUI

首先要对十字路口的路线进行分析,一个交通路口的路线总共有12条,分别是:

直行左转右转
N2SN2EN2W
S2NS2WS2E
E2WE2S E2N
W2EW2NW2S
这12条路线之间存在以下关系:

1、右转一直是通行状态

2、相对方向是同时通行或者左转的(即N2S通行时,S2N也是通行的,N2E通行时,S2W也是通行的)

3、东西、南北两个方向间歇同行,先直行,而后左转,之后是交叉方向

分析完了路线后就开始考虑具体的实现方式了:

首先,车是否通行是受到交通灯来控制的,也就是说当当前路线上有车并且交通灯为绿灯时车辆才可以同行,因为没有GUI,为了表明车辆通过,需要在控制台输出语句来表明车辆通过。这样就需要一个灯的对象来表明灯的状态,同时需要一个灯控制器的对象来控制灯的状态。考虑到灯是按照自己的固有规律运行的,不受路况和车辆的影响,为了保证其独立运行的特性,可以将灯控制器作为一个独立的线程运行。

为了模拟车的通过情况,张老师将每个路线都作为一个独立的线程来运行,实际上每条路用两个线程来模拟,一个线程用于在改线路上随机的产生待通过的车辆(向vechicles容器中添加元素),另一个线程用于释放这些车辆(向vechicles容器中取出元素),这样在运行时,路对象上的线程共有24个,整个系统有25个线程,在加上main,共26个线程。

基本思路出来后,就是具体的实现方式了:

这里把张老师的代码全部贴出来也没什么意思,还是分析关键点吧。

首先,为了表示出交通灯之间的逻辑关系,张老师为灯这个类定义了对面方向的灯和下个被点亮的方向的灯以及当前灯的状态三个字段,以及开、关两个方法:

/*当前灯是否为绿*/

private boolean lighted;

/*与当前灯同时为绿的对应方向*/

private String opposite;

/*当前灯变红时下一个变绿的灯*/

private String next;


以下是控制灯开关的方法:

/**

* 某个灯变绿时,它对应方向的灯也要变绿

*/

public void light(){

this.lighted = true;

if(opposite != null){

Lamp.valueOf(opposite).light();

}

System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");

}

/**

* 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿

* @return 下一个要变绿的灯

*/

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() + "-------->切换为" + next);

nextLamp.light();

}

return nextLamp;

}

而灯控制器这个类的作用也就是在间隔一定时间后打开某个灯关闭某个灯了,为了保证控制系统的唯一性,这个类使用了单例设计模式。

/*每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿*/

ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);

timer.scheduleAtFixedRate(

new Runnable(){

public  void run(){

System.out.println("来啊");

currentLamp = currentLamp.blackOut();

}

},

10,

10,

TimeUnit.SECONDS);
路可以分为两个部分,一部分向路中添加车辆,另一部分,则依据灯的状态,取出车辆。为了保证路能够访问灯的状态,灯需要提供一个方法:

public boolean isLighted(){

return lighted;

}

在mian函数中,为每个路分别建立一个线程(实际上是两个),并建立灯控制器的线程程序就可以运行了。

/**

* @param args

*/

public static void main(String[] args) {

/*产生12个方向的路线*/

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();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐