本帖最后由 王春晓 于 2013-5-12 23:10 编辑
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;
class Traffic {
/**
* @param args
*/
public static void main(String[] args) {
//建立12条路线
String[] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E_light","E2N_light","N2W_light","W2S_light"
};
for(int i=0;i<directions.length;i++){
new Road(directions);
}
//建立交通灯控制台
new LampController();
}
}
class LampController {
private Lamp currentLamp;
public LampController(){
currentLamp = Lamp.S2N;//开启S2N方向为当前灯,然后将灯点亮
currentLamp.light();
//每隔10秒将当前灯关闭,切换为下一盏灯
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
class Road {
private List<String> vechicles = new ArrayList<String>();//新建一个数组,将交通工具存放入其中,用List而不用ArrayList的原因,是应用面向接口的思想
private String name = null;//定义路的名字,实际是灯的名字
public Road(String name){
this.name = name;
//模拟汽车不断在路口随机增加的过程
ExecutorService pool = Executors.newSingleThreadExecutor();//创建一个单线程的线程池
pool.execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//通过sleep方法在路上随即间隔1~10秒出现一辆车
} catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);//车在路上增加i辆
}
}
});
//根据情况来定,每隔一定时间检查一次该路上的灯是否为绿灯,如果为绿,车辆通行。(间隔为1秒)
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);//定义定时器,用一个线程池创建一条线程
timer.scheduleAtFixedRate(
//会周期执行定时器的方法
new Runnable(){
public void run(){
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();//Enum的valueOf方法返回Enum对象
if(lighted){
System.out.println(vechicles.remove(0)+"is traveling!");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
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_light(null,null,true),E2N_light(null,null,true),N2W_light(null,null,true),W2S_light(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(name()+"lamp is green,下面总共应该有6个方向能看到汽车穿越路口");
}
//关掉当前灯和相反方向的灯,然后将下一盏灯返回为为当前灯
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);//next为什么总是打印null?
nextLamp.light();
return nextLamp;
}
}
//问题见注释标红部分 |