package jiaotongdeng;
public enum Lamp {
// 传入对面的灯,对面的灯为绿时,才通过,当我的灯变红时,通知下个灯变绿,默认是false,操作时需要改变状态
// 北往南 同方向 南往北
N2S("S2N", "E2W", false),
// 北向南
S2N(null, null, false),
// 东往西,同方向西往东
E2W("W2E", "E2S", false),
// 西向东
W2E(null, null, false),
// 东往南,西往北
E2S("W2N", "S2W", false),
// 西往北
W2N(null, null, false),
// 南往西,北往东
S2W("N2E", "N2S", false),
// 北往东
N2E(null, null, false),
// 右转弯4个灯,状态为常绿
N2W(null, null, true),
W2S(null, null, true),
S2E(null, null, true),
E2N(null, null, true);
private boolean lighted;// 标记,灯是否绿的
private String opposite;
private String next;
// 枚举的构造函数,枚举有参数,一定要有构造器初始化;
// 第一个参数对面灯的名字,第二个是下个灯的名字,再传入,通知下个灯变绿
private Lamp(String opposite, String next, boolean lighted) {
// 存储的不是灯,是灯的名字
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
public boolean isLighted() {
return lighted;
}
// 把对面的灯绿 ,车可以通过,这里操作时,需要把默认的false改为true
public void light() {
this.lighted = true;// 把我的灯变绿
// 传入的是对面灯的名字,有对面灯的时候,才把你变绿,我才有对应的灯,对应的没有对应的灯
if (opposite != null) {// enum枚举的方法,valueOf()返回带指定名称的指定枚举类型的枚举常量。,//枚举是一个常量
Lamp.valueOf(opposite).light(); // 把对应的灯用作枚举的方法传入,调用我的方法,去变绿
}// name()返回此枚举常量的名称,在其枚举声明中对其进行声明。
System.out.println(name() + " lamp is green 下面总有6个方向可以看到车通过....");
}
// 通过后,要把灯变红的方法
public Lamp blackout() {
this.lighted = false;// 把我的灯变红
if (opposite != null) {// 我如果有对应的灯,如果传进来的对应的灯不为null,就把我对应的灯变红,
Lamp.valueOf(opposite).blackout();// 传入对应的灯,他是没有对应的灯的,
// 其实这个程序中,把一条线路当作一个出口一个入口,出口有个灯,入口有个灯,状态是,一起变绿,或者一起变红,
// 但是我才有对应的灯,他不能说他有对应的灯,不然可是在递归调用,死循环了,
// 为什么说他没有对应的灯,在我的构造函数中,传入的就是对应的灯的地址,在c语言中深有体会,都是传入地址,只不过java说他是对象摆了,
}
//Lamp nextLamp = Lamp.valueOf(next);
Lamp nextLamp =null;
// 当前这条路线通车结束后,自己干完了事,还要把我的下个灯变绿(下一条线路的车干活),不然,别人怎么干活,
if (next != null) {
nextLamp=Lamp.valueOf(next);//返回一个枚举的对象,枚举名子
System.out.println("绿灯从" + name() + ".........切换为" + next);
nextLamp.light();//该枚举对象调用时,不为null,
}
return nextLamp;
}
}
package jiaotongdeng;
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;////TimeUnit.SECONDS,说明,单位是秒,
public class Road {
//用于装车的集合
private List<String> list=new ArrayList<String>();
// 路的名字
public static String name=null;
//有参数构造器
public Road(String name){
this.name=name;
System.out.println(this.name);
//创建线程池,线程池会用空闲的线程,来执行当前的任务,
ExecutorService pool=Executors.newSingleThreadExecutor();
//参数是一个Runnable()对象;
pool.execute(new Runnable(){
//以内部类实现的run方法,
public void run(){
try {
//Random,随机数是1到10,*1000是1到10秒
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int a=0;a<1000;a++){
//第几辆车,name名子
list.add(Road.this.name+" ---"+a);//生产车,把车加进集合去
}
}
});
//鉴于 Timer 的上述缺陷,Java 5 推出了基于线程池设计的 ScheduledExecutor。其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,
//因此任务是并发执行的,相互之间不会受到干扰。需 要注意的是,只有当任务的执行时间到来时,ScheduedExecutor 才会真正启动一个线程,其余时间
//调度ScheduledExecutor 都是在轮询任务的状态
//定时器,调度者,相当于组长,安排工作,定时安排工作量,安排任务给空闲的员工干活,这里的员工就是一个线程池,调度总是在查询有没有任务,有就安排
//ScheduledExecutorService读:是该久
//输入法,如果有繁体字,再按一次 Ctrl+Shift+F,该死的输入法
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);//调度器,最小雇佣数量 1;线程池至少有一个任务
timer.scheduleAtFixedRate(new Runnable(){
//实现run方法
public void run(){
if(list.size()>0){ //如果集合有车,
boolean lighted=true;
//boolean lighted=Lamp.valueOf(Road.name).isLighted();
if(lighted){
//马路上的最前面的一个车通过了马路,这模拟咋不像呢,开的动作都省了,删一个就是开了一个车!!
//每开过去一个车,等于要清空一台车,为什么一定是集合的第一台车呢!!有点死抠...
System.out.println(list.remove(0)+"通过了路口......");
}
}
}
},
1, //过多少秒后干事,调度者不断的在做,清除汽车动作,
1,//干完后,过多少秒接着干这个事,干完了接着干
TimeUnit.SECONDS);//枚举类
//TimeUnit.SECONDS,说明,单位是秒,
}
}
package jiaotongdeng;
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.E2W;
currentLamp.light();
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);// 调度器,最小雇佣数量
// 1;线程池至少有一个任务
timer.scheduleAtFixedRate(new Runnable() {
// 实现run方法
public void run() {
System.out.println("------------------");
currentLamp = currentLamp.blackout();
}
}, 10, // 过多少秒后干事,调度者不断的在做,清除汽车动作,
10,// 干完后,过多少秒接着干这个事,干完了接着干
TimeUnit.SECONDS);// 枚举类
// TimeUnit.SECONDS,说明,单位是秒,
}
}
package jiaotongdeng;
public class MainClass {
/**
* @author chenzhiyuan
*/
public static void main(String args[]) {
String[] directions = new String[] { "S2N", "S2W",
"E2W", "E2S", "N2S",
"N2E", "W2E", "W2N", "S2E", "E2N", "N2W", "W2S" };//是所有的枚举,//不是枚举里的参数
for (int a = 0; a < directions.length; a++) {
new Road(directions[a]);
}
new LampController();
}
}
|