------- android培训、java培训、期待与您交流! ----------
今天看了张老师的这个面试题讲解才感觉到自己在一个什么水平,继续努力学习,还需不断提升自己的能力!
继续学习巩固一些知识,对线程池的认识以及对定时器的熟练掌握。各个知识点融会贯通才能成为一名优秀的程序员。
交通信号灯题目及要求
1.异步随机生成按照各个路线行驶的车辆。
例如:
由南向而来去往北向的车辆 ---- 直行车辆
由西向而来去往南向的车辆 ---- 右转车辆
由东向而来去往南向的车辆 ---- 左转车辆
。。。
2. 信号灯忽略黄灯,只考虑红灯和绿灯。
3. 应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4.具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
5. 每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。
6. 随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。
7. 不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
画图分析:
分析对象,原则:谁拥有数据,谁就对外提供操作这些数据的方法。
路对象:
通过线程时间随机地产生汽车并存入集合众,跟据交通信号灯的变化移除汽车。
灯对象:
图中共有12条路线 , 就可以看作为12个固定的交通灯 ,由于每次都是在操作同一对象, 所以运用用Enum枚举类就更加方便。,
由于向右拐弯是不受灯控制的 , 所以4条右转弯的灯一直为绿(true) , 在剩下的8条路线中 , 路线是两两对应的 , S2N-N2S , S2W-N2E ,W2E-E2W , E2S-W2N , 并且第一组灯变红(false)时 , 第二组灯就变绿(true) , 依次往复 , 这样就明确的灯的对应和交替关系 。
信号灯控制器:
添加定时器,控制红绿灯变化。
路的代码:
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.TimeUnit;
public class Road {
private List<String> vehicles = new ArrayList<String>(); //创建集合,用来存放产生的汽车
String roadName = null;
Road(String roadName){ //路的构造方法
this.roadName = roadName;
ExecutorService pool = Executors.newSingleThreadExecutor(); //学习Executors类,创建独立线程。Java1.5
pool.execute(new Runnable(){ //匿名内部类
@Override
public void run() {
for(int i=1; i<1000; i++){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000); //
}
catch (InterruptedException e) {
e.printStackTrace();
}
//把车放进集合中
vehicles.add(Road.this.roadName+"_"+i); //外部类的局部变量的访问方式:外部类名.this.变量名
}
}
});
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //定义一个计划的线程池,线程的数量为1
//创建并执行此线程池,初始可以定时、并且后续具有周期性的方法.
//用于当交通灯为绿色时,移出当前路上的车辆
timer.scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
if(vehicles.size()!=0){
boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
if(lighted){
System.out.println(vehicles.remove(0)+" is traversing");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
信号灯:
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);
private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
private boolean lighted;
private String opposite;
private String next;
public boolean isLighted(){ //判断灯的状态
return lighted;
}
//灯变绿方法
public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(this.name()+"lamp is green");
}
//灯变红方法
public Lamp lightOff(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).lightOff();
}
System.out.println(next);
Lamp nextLamp = null;
if(next != null){
System.out.println("绿灯由"+name()+"变成"+next);
nextLamp = Lamp.valueOf(next);
//System.out.println("test");
nextLamp.light();
}
return nextLamp;
}
}
信号灯控制器:
public class LampController {
private Lamp currentLamp = null;
public LampController(){
currentLamp = Lamp.S2N; //定义初始变绿方向的灯
currentLamp.lightOn();
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1); //添加定时器,根据实际逻辑红绿灯不断交替
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currentLamp = currentLamp.lightOff(); //lightOff返回下一个当前状态等
}
},
10,
10,
TimeUnit.SECONDS);
}
}
编写住方法实现功能:
public class MainClass {
public static void main(String[] args) {
String[] roadNames = new String[]{
"S2N","S2W","E2W","E2S",
"N2S","N2E","W2E","W2N",
"S2E","E2N","N2W","W2S"
};
for(String roadName : roadNames){
new Road(roadName);
}
new LampController();
}
}