看到黑马程序员视频7k7K面试题(交通灯管理系统)了。。看了张老师的视频。。按照自己的想法加以修改了。。放上来。。希望大家指教下。
貌似也做到了要求的效果
要求:
交通灯管理系统
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
Ø 异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
Ø 信号灯忽略黄灯,只考虑红灯和绿灯。
Ø 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
Ø 具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
Ø 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
Ø 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
Ø 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
第一步创建交通灯类。
因为交通灯的数量是有限制的。就8个。所以想到枚举的方式创建。(张老师是12个交通灯有点和实际情况出入,就修改成了8个)
然后根据。每个交通灯的对面交通灯,下一个交通灯。以及交通灯亮的时间。通过交通灯控制器控制
package day1;
public enum TrafficLamp{
N2S("N2E","S2N",45,false),S2N("S2W","N2S",45,false),E2W("E2S","W2E",45,false),W2E("W2N","E2W",45,false),
W2N("S2N","E2S",15,false),E2S("N2S","W2N",15,false),N2E("W2E","S2W",15,false),S2W("E2W","N2E",15,false);
private String nextLamp;//因为这是枚举。前面的对象是不能调用后面没创建的对象的。所以用的String。然后给句get方法。或得下一个交通灯
private int time;
private boolean lighted;
private String oppositeLamp;//同上
public String getOppositeLamp()//这步可以不要。因为在控制交通灯的程序里我要加入name方面看控制情况。没法调用私有属性。所以
{
return oppositeLamp;
}
//创建交通灯构造方法,给下一个灯。对面灯。亮多少时间。是否亮。初始化值
TrafficLamp(String nextLamp,String oppositeLamp,int time,boolean lighted){
this.time=time;
this.nextLamp=nextLamp;
this.lighted=lighted;
this.oppositeLamp=oppositeLamp;
}
public int getTime(){
return this.time;
}
public boolean getLighted(){
return lighted;
}
public TrafficLamp nextLamp(){
return TrafficLamp.valueOf(nextLamp);
}
public TrafficLamp oppositeLamp(){
return TrafficLamp.valueOf(oppositeLamp);
}
public void setLight(boolean lighted){
this.lighted=lighted;
this.oppositeLamp().lighted=lighted;
}
}
创建路上的车。。。
package day1;
import 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.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class Road {
private List<String> vehicles=new ArrayList<String>();
private String roadName;//路的名字。。因为每条路是要和交通灯对应的。方便放行。new12条路的对象出来。
Road(String roadName){
this.roadName=roadName;
ExecutorService pool=Executors.newSingleThreadExecutor();//创建线程。给路上加上。随机在1-10秒加1辆车
pool.execute(new Runnable(){
public void run() {
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//操纵一个不能同步的集合。张老师为么没加锁呢。
synchronized(Road.class){
vehicles.add(Road.this.roadName+"_"+i);
}
}
}
});
}
//调用车的运行方式。有两种情况。有4个运行方向是不用被灯控制的会自行运行。还有8个运行时要受到灯控制的。
public void run(){
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);//创建线程。如果这个线路上的灯亮。每秒放行一次。
timer.scheduleAtFixedRate(new Runnable() {
public void run() {
if (vehicles.size()>0){
if(TrafficLamp.valueOf(Road.this.roadName).getLighted()){
synchronized(Road.class){
System.out.println(vehicles.remove(0)+"---is traveling");
}
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
//这是那四个不受交通灯控制的线路运行方式。少了一个对交通灯判断。原本是想加在上面的加一层判断。感觉每次都判断太啰嗦了就又加了个方法。
public void freeRun(){
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(new Runnable() {
public void run() {
if (vehicles.size()>0){
synchronized(Road.class){
System.out.println(vehicles.remove(0)+"---is traveling");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
package day1;
public class LampController implements Runnable {
public void run(){
TrafficLamp currentLamp=TrafficLamp.N2E;
currentLamp.setLight(true);//每次调用初始化一个交通灯点亮。对面的灯也就亮了
System.out.println(currentLamp.name()+currentLamp.getOppositeLamp()+":::::::::is lighted");
while(true){
try {
Thread.sleep(currentLamp.getTime()*1000);//等待灯亮的时间。
} catch (InterruptedException e) {
e.printStackTrace();
}
currentLamp.setLight(false);
currentLamp=currentLamp.nextLamp();
currentLamp.setLight(true);
System.out.println(currentLamp.name()+currentLamp.getOppositeLamp()+":::::::::is lighted");
}
}
}
主程序调用
package day1;
public class MainClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new LampController()).start();//创建灯亮线程独立于主线程
//每个方向的路线正常运行
new Road("N2S").run();
new Road("S2N").run();
new Road("E2W").run();
new Road("W2E").run();
new Road("W2N").run();
new Road("E2S").run();
new Road("S2W").run();
new Road("N2E").run();
new Road("N2W").freeRun();
new Road("W2S").freeRun();
new Road("S2E").freeRun();
new Road("E2N").freeRun();
}
}
交通灯控制方式