黑马程序员---交通灯管理系统
此项目是张孝祥老师的名作,在项目 里面张孝祥老师生动的运用了枚举来完成此项目,值得学习,望各位游客,认真观看,吸收知识
1.实现路上的所有交通灯
//这里我们用先用枚举enum来定义一个类Lamp,
package com.itcast.heima.traffic;
//这里用枚举来实现灯的方向
public enum Lamp {
//这里代表4个方向的灯
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 boolean lighted;// 定义个变量判断灯的状况(亮与没亮)
private String oppositeLamp;// 对面的灯
private String nextLamp;// 下一个灯
private Lamp(String opposite, String nextLamp, boolean lighted) {
this.oppositeLamp = opposite;
this.nextLamp = nextLamp;
this.lighted = lighted;
}
// 判断灯是否是亮的
public boolean isLighted() {
return lighted;
}
// 判断灯是否是绿灯
public void greeLamp() {
this.lighted = true;
System.out.println(name() + "..是绿灯.........其余的路上是红灯.......禁止通行.");
if (oppositeLamp != null) {
Lamp.valueOf(oppositeLamp).greeLamp();// 这是枚举的新功能,根据对于的枚举名返回一个枚举对象,在来调用Lamp的greeLamp的方法
}
}
// 判断灯是否是红灯
public Lamp readLamp() {
this.lighted = false;
if (oppositeLamp != null) {
Lamp.valueOf(oppositeLamp).readLamp();// 当前灯变红灯时,它对面的灯也要变红灯
}
Lamp next = null;
// 判断是否还有绿灯
if (nextLamp != null) {
System.out.println("五秒钟后切换灯了....");
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
next = Lamp.valueOf(nextLamp);
next.greeLamp();// 如果当前灯还有下一个灯时,就要把下个灯变成绿灯
}
return next;// 返回下一个亮的灯
}
}
2.实现交通灯所在的所有路
package com.itcast.heima.traffic;
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 {
List<String> vehicles=new ArrayList<String>();//创建一个在这条路上的车辆集合
private String name=null;
public Road(String name)
{
this.name=name;
ExecutorService pool=Executors.newSingleThreadExecutor();//创建一个线程
pool.execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2000; i++) {
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);//是线程在1到10秒内随机产生车辆
} catch (InterruptedException e) {
e.printStackTrace();
}
vehicles.add(Road.this.name+"_"+i);//将这条线路上的所有车辆添加到arraylist集合中
}
}
});
//这里要创建一个定时器,每隔一段的时间,就要放走一辆车
ScheduledExecutorService timertask=Executors.newScheduledThreadPool(1);//创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
timertask.scheduleAtFixedRate(new Runnable() {
public void run() {
if (vehicles.size()!=0) {
boolean lighted=Lamp.valueOf(Road.this.name).isLighted();//判断等是否是亮 绿灯
if(lighted)
System.out.println(vehicles.remove(0)+" 通过绿灯");//如果亮绿灯的话就放这辆车通过
}
}
},
0,
500,
TimeUnit.MILLISECONDS);//创建一个每隔500毫秒就执行一个runnable任务的定时器
}
}
3.实现所有交通灯的控制器,来管理交通灯
package com.itcast.heima.traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;//定义一个当前的灯
public LampController()
{
currentLamp=Lamp.S2N;//定义S2N这个灯为当前灯
currentLamp.greeLamp();//让当前灯变绿
ScheduledExecutorService timertask=Executors.newScheduledThreadPool(1);//创建一个线程池,线程池就一个定时器(timertask)线程
timertask.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
currentLamp=currentLamp.readLamp();//让这条路线每五秒钟就亮红灯,同时要记住当前灯
}
},
5,
5,
TimeUnit.SECONDS);//这是表示每个5秒钟,就要连环执行的
}
}
运行交通灯
package com.itcast.heima.traffic;
public class Main {
public static void main(String[] args) {
String[] road = new String[] { "S2N", "S2W", "E2W", "E2S", "N2S",
"N2E", "W2E", "W2N", "S2E", "E2N", "N2W", "W2S" };// 创建个路线集合
// 创建这12条路线,让这12条道路通车
for (int i = 0; i < road.length; i++) {
new Road(road[i]);
}
new LampController();//创建灯的控制器
}
}