A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 莫嘉伟 中级黑马   /  2013-2-28 17:54  /  1589 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package com.isoftstone.interview.traffic;

//因为灯的所有状态是可以确定的,并且灯之间的关系也是确定的,故将灯定义为枚举类
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),N2W(null,null,true),E2N(null,null,true),W2S(null,null,true);
       
        //用灯的亮灭代表红绿灯
        private boolean lighted;
        //定义一个属性代表与当前灯相对应的灯
        private String opposite;
        //定义一个next属性代表当前灯的下一个灯,即当前灯熄灭以后下一个该点亮的灯
        private String next;
        //枚举类的构造方法必须为私有,通过构造器可以传入灯对象的对应灯与下一个灯的属性,因此灯之间的关系在创建时就确
        //定了
        private Lamp(String opposite,String next,boolean lighted ){
                this.opposite=opposite;
                this.next=next;
                this.lighted=lighted;}
        private Lamp(){
               
        }
        //判断灯是否点亮并返回其状态
        public boolean isLighted(){
                return lighted;
        }
    //熄 灯方法,将当前灯和当前灯的对应灯熄灭并会返回当前灯的下一个灯
    public Lamp BlackOut(){
           
            this.lighted=false;
                            if(opposite!=null){
                                    Lamp.valueOf(opposite).BlackOut();}
                            Lamp nextLamp=null;
                            if(next!=null){
                                    nextLamp=Lamp.valueOf(next);
                                    System.out.println("绿灯从" + name() + "-------->切换为" + next);       
                                    nextLamp.Light();}
                            return nextLamp;
    }
    //开灯方法,将当前灯和其对应灯点亮
    public void Light(){
            this.lighted=true;
            if(opposite!=null){
                    Lamp.valueOf(opposite).Light();
                    }
            System.out.println(name() + " 转为绿灯,下面总共应该有6个方向能看到汽车穿过!");
    }
}

package com.isoftstone.interview.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;
  currentLamp.Light();
   ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
   timer.scheduleAtFixedRate(
      new Runnable(){
    public void run(){
     System.out.println("开始运作");
     currentLamp.BlackOut();
     
     }
    },
   10,
   10,
   TimeUnit.SECONDS);  
}


package com.isoftstone.interview.traffic;

import java.util.*;
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> vehicle=new ArrayList<>();       
        //定义路的名字,这里的名字主要是指路上车的行车方向
        private String name=null;
        //定义类Road类的构造器,传入一个name属性,并初始化
        public Road( String name){
                this.name=name;
                //使用Executros工厂产生一个单线程线程池pool,该线程池中传入的Runnable模拟不断有车开到路上的情景。
                //当路上的车小于1000辆时,通过线程的休眠来实现每隔一段时间(10秒以内)向路下增加一辆车
                ExecutorService pool=Executors.newSingleThreadExecutor();
                pool.execute(new Runnable(){
                                public void run(){
                                        for(int i=1;i<1000;i++){
                                                try{Thread.sleep((new Random().nextInt(10)+1)*1000);}
                                                catch(InterruptedException e){
                                                        e.printStackTrace();
                                                }
                                                vehicle.add(Road.this.name+"_"+i);
                                        }
                                }
                                });
                 /*定义一个延迟执行的线程池timer,模拟当绿灯亮时每隔一段时间就让一辆车,这里是的时
                 间间隔是1秒**/
                      ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
                      timer.scheduleAtFixedRate(
                          new Runnable(){
                              public void run(){
                                      if(vehicle.size()>0){
                                              boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
                                              if(lighted){
                                                      System.out.println(vehicle.remove(0)+"is travelling");
                                              }
                                      }
                              }
                              
                      },
                      1,
                      1,
                      TimeUnit.SECONDS);
                     
               
               
        }
}

package com.isoftstone.interview.traffic;

public class MainClass {
        public static void main(String[] args){
                String[] directions=new String[]{"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"};
                for(int i=0;i<directions.length;i++){new Road(directions[i]);}
                new LampController();
               
        }

}

   首先就是一个细节问题,就是Controller中的Run()方法应该是每十秒执行一次没错的,但是我照这代码执行的时候我好像只看到run()方法中的语句只执行了一次,后来我参考了老师的代码修改了一下其实就修该了Lamp类中点灯方法那个nxetLamp那里,我原来是在没判断nextLamp是否为null时就先把Lamp.valueOf(Lamp)附了给nextLamp,然后在nextLamp中直接调用Light方法,其实我认为这个虽然逻辑上有点怪,但无论如何定时器的运行是不会错的呀,输出语句怎么才运行一次呢;第二个问题就是关于为什么要把LampController单独封装成一个类,其实把它放在Lamp类中作为一个类方法这么做是不好还是不行?

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

2 个回复

倒序浏览
一起学习!!  坚持
回复 使用道具 举报
谢谢版主给分啊~在线等答
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马