30 交通灯管理系统
示意图:
按照面向对象的思考方式分析问题:谁拥有数据,谁就拥有操作数据的方法.
此项目涉及到3个对象,分别是:路,路灯,路灯控制器.
路线:12条,去掉四个方向的右拐弯,其余8条路线,两两相对,分成4组。
路灯:12个,同路线一样,只考虑4组路灯,可以通过枚举实现,右拐弯方向上的灯永远是绿灯.
路灯有变红和变绿的方法,当一个路灯变红或变绿时,对应相反方向上的路灯随之变红或变绿,当一个路灯变红时,如果有下一个路灯,那么下一个路灯要变绿.
汽车:用字符串表示汽车,通过对集合的增加和删除模拟汽车穿过。每条路线每隔一秒都会检查控制本路线的灯是否为绿,是则将本路线保存车的集合中的第一辆车移除,即表示车穿过了路口。
路灯控制器:具有操作红绿灯的方法。通过定时调用路灯的变绿和变红的方法,来完成红绿灯的交换.
package Default;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class TrafficLampDemo {//交通灯管理系统的测试类.
public static void main(String[] args) {
//通过字符串数组,表示路线的12个方向.
String []directions={"S2N","S2W","E2W","E2S",
"N2S","N2E","W2E","W2N",
"S2E","E2N","N2W","W2S"};
//遍历数组,并作为参数传递给Road类的构造函数。
for(String direction:directions){
new Road(direction);
}
//创建路灯控制器对象,完成对路灯的定时控制。
new LampController();
}
}
class Road{//定义Road类
//创建集合,用于模拟汽车穿过。
ArrayListvechicles =new ArrayList();
private String direction;
//定义Road类的构造函数,接收表示方向的字符串。
public Road(final String direction){
this.direction=direction;
//创建具有单线程的线程池,并执行随机往集合中增加表示汽车的字符串。
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
for (int i = 1; i < 1000; i++) {
try {
Thread.sleep((int)(Math.ceil((Math.random())*1000)));
} catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
vechicles.add(Road.this.direction+"_"+i);
}
}
});
//创建单线程的线程池,并在固定的时间频率类完成线程任务,通过对集合中元素的删除模拟汽车穿过。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
if(vechicles.size()>0){
boolean lighted=Lamp.valueOf(Road.this.direction).islighted();
if(lighted){//当此方向上的绿灯为绿灯时,汽车穿过。
System.out.println(vechicles.remove(0)+" is traveling ");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
enum Lamp{//定义表示路灯的枚举类,Lamp
//枚举常量,表示12个方向上的路灯。
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","N2S",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 String oppsite;
private String next;
private boolean lighted;
//定义枚举类的构造函数,接收三个参数:相反方向的灯,当前灯的下一个灯,当前灯的状态。
private Lamp(String oppsite,String next,boolean lighted){
this.oppsite=oppsite;
this.next=next;
this.lighted=lighted;
}
//创建判断灯是否为绿灯的方法。
public boolean islighted(){
return lighted;
}
//创建路灯变绿的方法。
public void light(){
this.lighted=true;
//当有相反方向的灯时,相反方向的灯也变绿。
if(oppsite!=null){
Lamp.valueOf(oppsite).light();
}
System.out.println(name()+" lamp is green,下面总共能看到6个方向的车穿过");
}
//创建路灯变红的方法
public Lamp blackOut(){
this.lighted=false;
//当有相反方向的灯时,相反方向的灯也变红。
if(oppsite!=null){
Lamp.valueOf(oppsite).blackOut();
}
Lamp nextlamp=null;
//判断当前变红的灯,是否有下一个灯,如果有就把下一个灯变绿,并返回下一个灯。
if(next!=null){
nextlamp=Lamp.valueOf(next);
nextlamp.light();
System.out.println("绿灯从 "+name()+"------->切换成"+next);
}
return nextlamp;
}
}
class LampController{//定义路灯控制器类。
//定义表示当前路灯的变量。
private Lamp currentlamp;
//定义构造函数
public LampController(){
currentlamp=Lamp.S2N;
//首先把当前路灯变绿。
currentlamp.light();
//创建线程池,在固定频率类完成红绿灯的交换。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
currentlamp=currentlamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}