黑马程序员技术交流社区
标题:
交通灯的面试题,自己写的发现运行的时候非常耗CPU
[打印本页]
作者:
清水
时间:
2012-12-29 00:03
标题:
交通灯的面试题,自己写的发现运行的时候非常耗CPU
张老师的代码基本上不怎么耗费cpu。
下面是我自己的代码,非常占用cpu。
不知有什么工具能帮忙找出耗费cpu的代码?
import java.util.*;
public class Traffic{
public static void main (String[] args){
//定义一个字典,准备用来建立Road对象,不然会搞死人
String[] dics = {"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
//两句话建立12个road对象,爽
for(int i = 0; i <dics.length;i++){
new Road(dics[i]);
}
//建立交通灯控制对象
LampController lc = new LampController();
//设置初始灯为S2N
Lamp currentLamp = Lamp.S2N;
//交通灯控制对象在主线程中
while (true){
//每11秒对把当前的绿灯关闭,返回下一组灯。
mySleep(11000);
currentLamp = lc.offLamp(currentLamp);
}
}
//避免多次try catch,定义一个mysleep方法。
public static void mySleep(long millinSec){
try {
Thread.sleep(millinSec);
}
catch(Exception e){
}
}
}
//交通灯控制,很简单,就一个方法,关闭灯。
class LampController{
Lamp Lamp;
LampController(){
}
Lamp offLamp(Lamp lamp){
return lamp.setBlank();
}
}
class Road{
private String name= null;
//因为是先进先出,所以只适用列表的头和尾,所以使用LinkedList,另外加上同步代码保证线程安全。
private List<Integer> cars = Collections.synchronizedList( new LinkedList<Integer>());
//一生成Road对象,就开始来车和车通过的线程。
Road(String name){
this.name =name;
Thread t1 = new Thread(new RoadAddCar(name, cars));
Thread t2 = new Thread(new RoadCarPass(name, cars));
t1.start();
t2.start();
}
}
//实现Runnable接口,准备来车的线程
class RoadAddCar implements Runnable{
//定义使用到的变量,用于构造函数和打印结果。
private String name ;
private Integer carID = 1;
private List<Integer> cars;
//传入路名和车的队列。
RoadAddCar(String name,List<Integer> cars){
this.name = name;
this.cars = cars;
}
public void run(){
while (true){
//0.5秒-2.5秒时间,随机来车。来一辆车就打印一次。
cars.add(carID);
System.out.println(name+"来车ID:" + carID);
carID = carID + 1;
Traffic.mySleep((long)(Math.random()*2000 + 500));
}
}
}
//实现Runnable,准备车通行的线程
class RoadCarPass implements Runnable{
private List<Integer> cars;
private String name ;
private Integer carID;
//构造函数传入路名和车的队列。
RoadCarPass(String name,List<Integer> cars){
this.name = name;
this.cars = cars;
}
public void run (){
while (true){
//如果绿灯则考虑通行
if (Lamp.valueOf(name).isLighted()){
//当然这条路还得有车才行。
if (cars.size() > 0){
carID = cars.remove(0);
//因为是只有花1秒时间通过了路口,才会打印结果,所以会在运行结果中看到,红灯亮了,车才通过。
//因为Lamp.setBlank()中,红灯亮了,过1秒之后,下组灯的绿灯才会亮,所以不会出现交通事故。
Traffic.mySleep(1000);
System.out.println(" "+name+"路,ID:"+carID+"通过路口,耗时1000毫秒");
}
}
//因为如果此路口是红灯,则上述判断不成立,如果下面不休息,系统资源消耗过大。
else
Traffic.mySleep(1000);
}
}
}
//枚举,虽然在基础视频上没有讲,但这两个面试题,让我觉得枚举很有用。这个题目做完之后,对枚举的认识有提高了。
enum Lamp{
//定义了每个灯所对应的灯和下一个灯,默认为红灯。
S2N("N2S","S2W",false), S2W("N2E","E2W",false), E2W("W2E","E2S",false), E2S("W2N","S2N",false),
N2S("S2N","N2E",false), N2E("S2W","W2E",false), W2E("E2W","W2N",false), W2N("E2S","N2S",false),
//右转的路的都为绿灯
S2E(null,null,true), E2N(null,null,true), N2W(null,null,true), W2S(null,null,true);
private String opposite = null;
private String next = null;
private boolean lighted = false;
//Lamp对象的构造方法。
Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}
public boolean isLighted(){
return this.lighted;
}
public String nextLamp(){
return this.next;
}
//开绿灯,打印到控制台
private void setL(Lamp lamp){
lamp.lighted = true;
System.out.println("== "+lamp.name() + "路绿灯亮,车辆可以通过");
}
private void setLight(){
//一次开2个绿灯,比感觉比递归更容易让人理解
setL(this);
setL(valueOf(this.opposite));
}
//开红灯,打印到控制台
private void setO(Lamp lamp){
lamp.lighted = false;
System.out.println("XX "+lamp.name() + "路红灯亮,车辆停止");
}
public Lamp setBlank(){
//一次开2个红灯,比感觉比递归更容易让人理解
setO(this);
setO(valueOf(this.opposite));
//因为车辆通过需时1秒,所以在红灯亮了之后1s,才打开下一轮灯的绿灯。
Traffic.mySleep(1000);
valueOf(this.next).setLight();
return valueOf(this.next);
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2