黑马程序员_java交通灯系统案例

---------------------- android培训java培训、期待与您交流! ----------------------


思路

    在任何一个十字路口,一辆车只会有三个方向去行驶:执行、左转、右转。直行和左转是受交通等影响的,而右转是不受交通等影响的。一般情况下,直行方向需要等交通等变绿才可通行,而左转车辆要等直行方向交通灯变红,而且左转方向是绿灯才可通过,而右转随时可以通行,就像于右转一直是绿灯。通过观察生活,我们知道,道路两侧交通灯是对称的,东向西信号灯变绿,西向东信号等也会变绿,这样,我们在编程时只需考虑每个驶向的一侧信号灯变化即可。

       在编程时,首先考虑交通等的变化,这样,我们先为交通灯定义一个枚举类,在这个类中有十二个成员,分别代表每个方向的交通信号灯

    public enum Lamp {
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("S2E","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);

}

     上面的枚举成员可分为三类,枚举成员的第一行为我们主要考虑的交通灯,第二行与第一行对应,所以不用考虑,第三行都为右转道路,只要标记为随时可通行即可。

      在这个枚举中,我们需要为每个成员保存相应的成员变量。首先我们需要一个boolean型变量标记该道路是否可通行,然后需要一个变量保存此信号灯的对面信号灯是哪个信号灯,因为这俩个信号等的信号变化是一样的,所以我们在设置变换灯的成员方法时将此时要变化的灯和它对面的灯都变化即可。最后,我们需要一个变量保存下一次变化的灯。我们还需要两个三个成员方法,分别是此路上否为绿灯、变成绿灯和变成红灯。

public enum Lamp {
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("S2E","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 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;
 }
 
 public void light()//变成绿灯
 {
  this.lighted=true;
  if(opposite!=null)
  {
   Lamp.valueOf(opposite).light();
  }
  System.out.println(name()+"lamp is green.下面总共有6个方向能看到有车通过");
 }
 
 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;
 
 }
}
     上面是交通灯的类,下面来说说道路类。

     在道路类的构造方法中,使用了线程池,因为每个道路中的车辆数量都是随机生成的,所以我们将每条道路都建立两个线程。一个线程是车辆驶入,另一个线程车辆驶出。在我们的构造方法中,在1-10秒钟内每条道路随机驶入一个车辆对象。  假如灯为绿灯并且有车辆等待,每过1秒驶出一辆车。

public class Road {
 List<String> vechicles=new ArrayList<String>();

 private String name=null;
 public Road(String name)
 {
  this.name=name;
 
  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) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
     vechicles.add(Road.this.name+"_"+1);
    }
    
   }
  });
 
  ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);//驶出车辆
  timer.scheduleAtFixedRate(
    new Runnable(){
     public void run(){
      if(vechicles.size()>0)
      {
       boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
       if(lighted)
       {
        System.out.println(vechicles.remove(0) + "is tranversing!");
       }
      }
     }
    },
    1,
    1,
    TimeUnit.SECONDS);
  }
}

   下面就该来考虑一个交通灯控制类,控制每条道路上的交通灯,因为同一时间,只有两个交通灯为绿,并且这两个灯是相对的,所以我们可以只在此类中保存一个交通灯对象,此外需要一个单独的线程来控制信号的改变,在这个线程中,我们只需要调用信号灯对象的blackOut()方法即可,这个方法可以使此时绿灯变红,并且使下一个灯变绿,返回此时变绿灯的对象。

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(){
     currentLamp= currentLamp.blackOut();
     
    }
   },
   10,
   10,
   TimeUnit.SECONDS);
 }
}
最后,创建一个主函数,分别创建12条道路对象和交通灯控制类对象即可。

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



---------------------- android培训java培训、期待与您交流! ----------------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值