----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
/**
* 以初始灯为S2N为绿灯示例:(结合程序说明示意图中的情况一->情况四的灯变化) 初始状态所有灯均为红灯 ①
* S2N->S2N.turnGreen();->S2N 绿 ,N2S 绿,S2W 红,N2E 红 ②
* 10秒后->S2W=S2N.turnRed();->S2N 红,N2S 红,S2W 绿,N2E 绿 ③
* 10秒后->E2W=S2W.turnRed();->S2W 红,N2E 红,E2W 绿,W2E 绿 ④
* 10秒后->E2S=E2W.turnRed();->E2W 红,W2E 红,E2S 绿,W2N 绿 ......
*
* @author lazy
*
*/
public class LampControlSystem {
private TrafficLamp currentGreenLamp;// 记住当前的绿灯
public LampControlSystem() {
currentGreenLamp = TrafficLamp.S2N;// 如果用TrafficLamp使用递归,你不能使用
// oppsite和next均为null的路线,因为无法完成切换
// 不使用,可以任意选一条路线
currentGreenLamp.turnGreen();// 把S2N路线上的灯置为绿灯
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
currentGreenLamp = currentGreenLamp.turnRed();// 将当前绿灯切换为红灯,
// 同时记录nextLamp(下一次变绿的灯),很巧妙
}
}, 10, 10, TimeUnit.SECONDS);// 定义一个计时器每隔10秒一切换
}
}
.交通灯管理系统:
模拟实现十字路口的交通灯管理系统逻辑,具体需求如下:
1.异步随机生成按照各个路线行驶的车辆
例如:
由南而来去往北向的车辆右转车辆
由东而来去往南向的车辆---左转车辆
.....
2.信号灯忽略黄灯,只考虑红灯和绿灯
3.应考虑左转车辆受信号灯控制,右转车辆不受信号灯控制
4.具体信号灯控制逻辑与现实生活中普通灯控制逻辑相同,不考虑特殊情况下的控制逻辑
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆
5.每辆车通过路口时间为1秒(可通过sleep模拟)
6.随机生成车辆时间间隔 以及 红绿灯交换时间间隔自定,可以设置
7.不要求实现GUI,只考虑系统逻辑实现,可通过log方式展现程序运行结果
*/
public class Main {
public static void main(String[] args) {
// TODO 自动生成的方法存根
String[] directions = { "S2N", "S2W", "N2S", "N2E", "E2W", "E2S",
"W2E", "W2N", "W2S", "E2N", "S2E", "N2W" };
for (int i = 0; i < 12; ++i)
new Road(directions[i]);// 每条路线上均有两个线程池(每个线程池中一个线程)分别控制增减车辆
new LampControlSystem();
}
}
public class Road {
private String roadName; // 路的名字
private List<String> vehiles = new ArrayList<String>(); // 用于装路上的车辆
public Road(String roadName) {
this.roadName = roadName;
/*
* 单独线程操作增加车量
*/
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
// TODO Auto-generated method stub
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vehiles.add(Road.this.roadName + "--" + i);// 路名+标号构成车辆名
}
}
});
/* 单独线程操作减少车辆 */
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (vehiles.size() != 0) {
boolean lighted = TrafficLamp.valueOf(Road.this.roadName)
.isLighted();// 根据路名来
if (lighted) // 获取当前灯的状态
System.out.println(vehiles.remove(0)
+ "...travel crossing!");// 试想车辆排成一个队列,当灯为绿灯时,
// 不断经过路口的均是队头车辆
// 要想判断当前路线上灯的状态还需要借助于灯管理系统
}
}
}, 1,// delay
1, // period
TimeUnit.SECONDS);
}
/*当我们在创建一个路线对象时同时使用两个线程池(内部均只有一个线程)各自独立控制车辆的增加和减少*/
}
enum TrafficLamp {
/* 在写next:满足同方向先直行后左转,然后下一个同方向先直行后左转 */
S2N(false, "N2S", "S2W"), S2W(false, "N2E", "E2W"), // 2代表to(4代表for),不止一种写法
W2E(false, "E2W", "W2N"), W2N(false, "E2S", "N2S"),
N2S(false, "S2N", "N2E"), N2E(false, "S2W", "W2E"), E2W(false, "W2E", "E2S"), E2S(
false, "W2N", "S2N"),
S2E(true, null, null), N2W(true, null, null), // 各个路口的右拐灯恒绿,没有对应的灯和下一盏灯
W2S(true, null, null), E2N(true, null, null);
private boolean lighted;// 当前灯的状态 true为绿灯,flase为红灯
private String opposite;// 该灯对应的灯(同红同绿的灯),这里不使用TrafficLamp类型,例如:S2N(N2S)
// N2S还没有定义(不能先使用后定义)
private String next; // 该灯对应的下一盏要改变状态的灯,也就是直行后的左转灯
private TrafficLamp(boolean lighted, String opposite, String next) {// 初始化以上三个成员变量
this.lighted = lighted;
this.opposite = opposite;
this.next = next;
}
public boolean isLighted() {// 对外提供一个获取当前灯的状态
return lighted;
}
public void turnGreen() {// 当前灯的状态变成绿灯,同时对应的灯也变成绿灯
lighted = true; // 例如:N2S为绿->S2N为绿,N2E为红
System.out.println(name() + "...变绿");
if (opposite != null)
TrafficLamp.valueOf(opposite).lighted = true;
System.out.println(TrafficLamp.valueOf(opposite).name() + "...变绿");
/*
* if(next!=null){ //这个可以不用,因为初始值的lighted均为false
* TrafficLamp.valueOf(next).lighted=false;
* TrafficLamp.valueOf(TrafficLamp
* .valueOf(next).opposite).lighted=false; }
*/
}
public TrafficLamp turnRed() {// 当前灯的状态变成红灯
lighted = false;
System.out.println(name() + "...变红");// 以下打印语句均为调试用
if (opposite != null)// 右拐灯opposite==null
TrafficLamp.valueOf(opposite).lighted = false;
System.out.println(TrafficLamp.valueOf(opposite).name() + "...变红");
TrafficLamp nextLamp = null;
if (next != null) {// 不但需要把下一盏灯变绿,还要把下一盏灯的oppsite对应的灯也要变绿
nextLamp = TrafficLamp.valueOf(next);// next不为null才能valeOf
nextLamp.lighted = true;
System.out.println(nextLamp.name() + "...变绿");
TrafficLamp.valueOf(nextLamp.opposite).lighted = true;
System.out.println(TrafficLamp.valueOf(nextLamp.opposite).name()
+ "...变绿");
}
return nextLamp;// 会记录下一盏变绿的灯时用到
}
}
----------------------- android培训、java培训、java学习型技术博客、期待与您交流! ----------------------