package com.TianRanDai.interView.traffic;
/**
* 测试调度总流程
* @author hadoop
*
*/
public class Test {
public static void main(String[] args) throws Exception {
//获取交通灯枚举的Class
Class<?> clazz = Lamp.class;
if(clazz.getEnumConstants()!=null){
//反射出所有的交通灯类型
//注意,可以直接用一组定义字符串的方式来生成交通灯的名称,本人偷懒,用简单的反射代码来实现了
Lamp[] lamps = (Lamp[]) clazz.getEnumConstants();
for(Lamp lamp :lamps){
//迭代创建12条马路
new Road(lamp.name());
}
//启动交通灯控制器
new LampController(lamps[0]);
}
}
}
package com.TianRanDai.interView.traffic;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 马路的实例
* @author hadoop
*
*/
public class Road {
//马路的名字
private String name;
//在马路上穿行的车辆
private List<String> vechicles = new CopyOnWriteArrayList<String>();
public Road(String name){
this.name = name;
//调用马路的初始化方法
init(name);
}
/**
* 马路的初始化方法
* @param name
*/
private void init(String name) {
//创建一个普通的单线程池
ExecutorService pool =Executors.newSingleThreadExecutor();
//启动一个线程
pool.execute(new Runnable(){
@Override
public void run() {
//在该迭代中创建1000辆车加入到车辆集合中
for(int i =0;i<1000;i++){
try {
//随机(1~10)秒创建一辆车
Thread.sleep(((new Random().nextInt(9))+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);
}
}
});
//创建一个调度器线程池,用于执行定时器线程
ScheduledExecutorService scheduledpool = Executors.newScheduledThreadPool(1);
//按固定频率调用线程
scheduledpool.scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
if(!vechicles.isEmpty()){
boolean lighted = Lamp.valueOf(Road.this.name).isLight();
if(lighted){
//如果是绿灯,则开走一辆车
System.out.println(vechicles.remove(0)+" is traversing!");
}
}
}
},
1,//延迟
1,//频率
TimeUnit.SECONDS);//单位,按秒来计算
}
}
package com.TianRanDai.interView.traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 交通灯控制器
* @author hadoop
*
*/
public class LampController {
//交通灯属性
private Lamp cuurentLamp;
LampController(Lamp lamp){
cuurentLamp = lamp;
//将当前的灯变绿
cuurentLamp.light();
//创建一个调度线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(1);
//启动固定频率的任务
scheduledPool.scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
cuurentLamp = cuurentLamp.dark();
}
},
20,//延迟
20,//周期
TimeUnit.SECONDS);//单位
}
}
package com.TianRanDai.interView.traffic;
/**
* 灯的枚举,代表12种交通灯的集合
* 注意:一下灯亮了,都表示变“绿”了
* 请记住一个设计原则:谁拥有数据,便是谁来操作数据
* @author hadoop
*
*/
public enum Lamp {
/**
* 灯的实例类
*/
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 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 void light() {
//将灯变绿
this.lighted = true ;
System.out.println(name()+" 灯亮了");
if(oppsite!=null){
//将与该灯反向的灯也变亮
Lamp.valueOf(oppsite).light();
}
System.out.println("将会有6个方向的车行驶!!");
}
/**
* 灯变红的方法
* @return
*/
public Lamp dark(){
//将灯变红
this.lighted = false ;
System.out.println(name()+" 灯变暗了");
if(oppsite!=null){
//将与该灯反向的灯也变红
Lamp.valueOf(oppsite).dark();
}
Lamp nextLamp = null;
if(next!=null){
nextLamp = Lamp.valueOf(next);
//将该灯的下一个灯变绿
nextLamp.light();
}
//返回下一个灯
return nextLamp;
}
/**
* 判断该灯的状态
* @return
*/
public boolean isLight(){
return lighted;
}
}
package com.TianRanDai.interView.traffic;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* 此测试类是测试结果,若同时穿行的车辆的路的数量为6,则交通灯调度成功,否则失败
* 测试环境,绿灯20秒
* @author hadoop
*
*/
public class Test2 {
public static void main(String[] args) {
List<String> checker = new ArrayList<String>();
List<String> beChecks = new ArrayList<String>();
//取自Test测试类的测试结果数据
String s = "S2N_0 is traversing!E2N_0 is traversing!S2N_1 is traversing!S2E_0 is traversing!N2W_0 is traversing!W2S_0 is traversing!E2N_1 is traversing!S2N_2 is traversing!N2S_0 is traversing!E2N_2 is traversing!N2S_1 is traversing!S2E_1 is traversing!W2S_1 is traversing!S2N_3 is traversing!E2N_3 is traversing!N2W_1 is traversing!S2N_4 is traversing!N2S_2 is traversing!S2E_2 is traversing!W2S_2 is traversing!E2N_4 is traversing!W2S_3 is traversing!";
String [] arr = s.split("!");
for(String record :arr){
StringTokenizer st = new StringTokenizer(record);
beChecks.add(st.nextToken().split("_")[0]);
for(String beCheck:beChecks){
if(checker.contains(beCheck)){
continue;
}else{
checker.add(beCheck);
}
}
}
System.out.println(checker.size());
}
}