交通灯调度系统
十字路口上总共有12条线路,每条路上的汽车数是随机添加的,当该路线上绿灯亮时,该线路上的汽车按一定时间减少,表示其通过路口,红灯时不减少,但是添加会一直进行。
张孝祥老师这道题做得挺漂亮的,下面学习一下张老师的代码。
交通灯类的实现
public enum Lamp {
S2N1 ("N2S5" ,"S2W2" , false) ,S2W2 ( "N2E6", "E2W3", false ), E2W3( "W2E7", "E2S4", false ), E2S4( "W2N8", "S2N1", false ),
N2S5 (null , null, false) , N2E6( null, null, false) , W2E7( null, null, false) , W2N8( null, null, false) ,
S2E9 (null , null, true) , E2N10( null, null, true) , N2W11( null, null, true) , W2S12( null, null, true) ;
private Lamp( String
opposite, String
next, boolean lighted ) {
this. next = next;
this. opposite = opposite;
this. lighted = lighted;
}
private String next ;
private String opposite ;
private boolean lighted;
public boolean isLighted (){
return lighted ;
}
public void lightOn (){
this. lighted= true;
if (! this. opposite. equals( null ))
Lamp .valueOf (opposite ). lighted= true;
System . out. println( name () + "
lamp is green,下面总共应该有6个方向能看到汽车穿过!" );
}
public Lamp
lightOff(){
this. lighted= false;
if (! this. opposite. equals( null ))
Lamp .valueOf (opposite ). lighted= false;
if (! this. next. equals( null ))
Lamp .valueOf (next ). lightOn ();
return Lamp. valueOf( next) ;
}
}
首先这是一个枚举类,十二条线路的交通灯,分成三种构造,现实的交通灯也是这样的,分成4种情况。开灯表示绿灯亮,同时把该线路的相反方向的灯也打开,关闭也同理,关闭的同时打开下一条线路的灯,如此循环不断。
Lamp系统
用于控制线路等的开关间隔。
public class LampSystem {
private Lamp currentlamp ;
LampSystem (){
currentlamp= Lamp. S2N1;
currentlamp. lightOn ();
ScheduledExecutorService
contrl =Executors .newScheduledThreadPool ( 1) ;
contrl .scheduleAtFixedRate ( new Runnable (){
public void run () {
currentlamp= currentlamp. lightOff ();
// TODO Auto-generated method
stub
}}, 10, 10, TimeUnit. SECONDS );
}
}
这里采用的是调控线程,每隔一段时间就会执行一次run,非常好用的时间控制器。因为Lamp对象只知道自己怎么关灯和怎么开灯,但是什么时候开,什么时候关,它是不知道的,这个事情Lamp系统才是最清楚的。
public class Road {
private List< String> Vechicles = new ArrayList <String >() ;
private String name ;
public Road( String
name ) {
super ();
this. name = name;
ExecutorService
addcar =Executors .newSingleThreadExecutor ();
addcar .execute ( new Runnable (){
public void run () {
for (int i= 1; i< 1000; i++ ){
try {
Thread .sleep ((new Random() .nextInt ( 10) +1 )* 1000 );
} catch (Exception e ) {
// TODO: handle exception
e .printStackTrace ();
}
Road . this. Vechicles. add( "vechicle" +"i" );
}
}
});
ScheduledExecutorService
cross =Executors .newScheduledThreadPool ( 1) ;
cross .scheduleAtFixedRate ( new Runnable (){
public void run () {
// TODO Auto-generated method
stub
if (Road . this. Vechicles. size() >0 ){
if (Lamp .valueOf (Road . this. name) .isLighted ())
System . out. println( Road. this. name+ ">>>" +Road . this. Vechicles. remove( 0 ) + "
is traversing !" );
}
}
}, 1, 1, TimeUnit. SECONDS ); }
}
这里用的是两条独立的线程,一条线程用于添加车辆,每条线路都能随机时间(1到10秒)添加汽车。另一条线程是用来描述汽车通过路口的情形,当绿灯时,检测线路上是否有车,有车就移除前面一辆,没有就等待,下一秒继续检测。
测试类
测试系统。
// TODO Auto-generated method
stub
String [] directions= {"S2N1" ,"S2W2" ,"E2W3" ,"E2S4" ,"N2S5" ,"N2E6" ,"W2E7" ,"W2N8" ,"S2E9" ,"E2N10" ,"N2W11" ,"W2S12" };
for (int i= 0; i< directions. length; i++ )
new Road( directions [i ]);
new LampSystem() ;
}
/* S2N1
lamp is green,下面总共应该有6个方向能看到汽车穿过!
W2S12>>> vechiclei is
traversing !
N2S5>>> vechiclei is
traversing !
W2S12>>> vechiclei is
traversing !
S2N1>>> vechiclei is
traversing !
S2E9>>> vechiclei is
traversing !
S2N1>>> vechiclei is
traversing !
E2N10>>> vechiclei is
traversing !
N2W11>>> vechiclei is
traversing !
N2S5>>> vechiclei is
traversing !
N2W11>>> vechiclei is
traversing !
N2S5>>> vechiclei is
traversing !
S2E9>>> vechiclei is
traversing !
N2W11>>> vechiclei is
traversing !
S2W2
lamp is green,下面总共应该有6个方向能看到汽车穿过!*/
把线路对象和Lamp系统对象构建好就行。会自动执行构造函数里的线程。