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

© 燕国庆 高级黑马   /  2013-4-6 09:07  /  1850 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 燕国庆 于 2013-4-7 06:37 编辑

public class MainClass {
/**
  * @param args
  */
public static void main(String[] args) {
  // TODO Auto-generated method stub
  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);//在实例化路线对象的时候,当将四个向右转弯的路线实例化之后,那四条路上的车是不是一直在通行,不用考虑路灯,
                                        //然而为什么每次在运行程序的时候,都会是“S2N,N2S”着两条路线先执行,而不是那四条右转弯的车辆相同行呀,
                                        //主函数的线程是按顺序执行的,按理说应该先创建完所有的路线,(此时那四条路线已经存在,并且lighted为true,
                                                           此时可以进行remove()方法了呀。)
                                      //灯的控制器是在下面一行才创建的应该后执行,可是为什么每次执行的都是:N2S  Lamp is green!下面将会有六个方向的车可以通行!
                                                                                                                                                               S2N  Lamp is green!下面将会有六个方向的车可以通行!
  }
  new LampControl();//灯的控制器是怎么样控制路灯的变化的?是必须有它才能开启整个交通灯系统的运作吗?      
}
}


import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
private List<String> vehicles=new ArrayList<String>();
String name=null;
public Road( String name){
  this.name=name;  
  ExecutorService pool=Executors.newSingleThreadExecutor();
  pool.execute(new Runnable(){
   @Override
   public void run() {
    // TODO Auto-generated method stub
    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();
     }
     
     vehicles.add(Road.this.name+"---"+i);
    }   
   }   
  });
  
  ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(
    new Runnable(){
     @Override
     public void run() {
      // TODO Auto-generated method stub
      
      if(vehicles.size()>0){
       boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
      // System.out.println(Road.this.name);
      
       if(lighted)
       {
        //System.out.println(lighted);
        System.out.println(vehicles.remove(0)//因为车辆集合由List创建的,根据List的特性,remove(0)表示的就是移除列表中的第一个元素,
                 //然后后面的元素向左移动(并且索引减 1),这样每次都移除的就是排队排在前面的车子,
                 //你可以想象,交通灯前的车子,肯定是按照顺序,离路口近的车先行驶过路口,然后后面的车子跟上,符合道道路现状.
                 // remove(0)表达的就是这个意思      
          + "---is travaling!");
       }
      }
     }
     
    },
    1,
    1,
    TimeUnit.SECONDS);
  
}
}

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampControl {

private Lamp currentlamp;

public LampControl(){
  
  currentlamp=Lamp.S2N;
  currentlamp.light();
  
  ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(
    new Runnable(){
     @Override
     public void run() {
      // TODO Auto-generated method stub
      currentlamp= currentlamp.lightOut();
      
     }
     
    },
    10,
    10,
    TimeUnit.SECONDS);
}

}


请明白人指点迷津,谢谢!!!

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

6 个回复

正序浏览
谢谢大家的帮忙。
回复 使用道具 举报
燕国庆 发表于 2013-4-6 22:44
即便没有new LampControl();只有那四条向右的路,他们也会一直运行的,这个我测试过,此时只有他们四个切 ...

加上new LampControl();之后,S2N,S2W,E2W,E2S这四条路中总是S2N(N2S)先执行,因为:currentLamp = Lamp.S2N;currentLamp.light();首次初始的是S2N;那四条常绿路和另外两条的主路的执行顺序是随机的。你多运行几次看看。我运行的第一次是:

N2S灯变绿了,下面总共应该有6个方向能看到汽车穿过
S2N灯变绿了,下面总共应该有6个方向能看到汽车穿过
W2S方向---第1车 is traversing !
S2E方向---第1车 is traversing !
S2E方向---第2车 is traversing !
N2S方向---第1车 is traversing !
N2W方向---第1车 is traversing !
S2N方向---第1车 is traversing !

首次通车的不一定都是S2N,但一定有S2N。这次明白了木有?
回复 使用道具 举报
赵家阳 发表于 2013-4-6 11:32
1,至于为什么每次都是S2N先通行,这两句代码应该可以解释了,currentlamp=Lamp.S2N;     currentlamp.ligh ...

即便没有new LampControl();只有那四条向右的路,他们也会一直运行的,这个我测试过,此时只有他们四个切换,而加上new LampControl()之后,为什么会是先执行:每次都是S2N先通行。那四条常绿路线不是优先于被LampContol中控制的那个S2N路线执行吗?
回复 使用道具 举报
jdzzlf 发表于 2013-4-6 11:11
1、首先我要回答的是,程序是自上而下,顺序执行。
2、我们来分析下,main()这个类,这个类先是产生12条路 ...

你可以一步步分析下,new road(),只是将路线加进了private List<String> vechicles = new ArrayList<String>()这个集合中,而下面的那个定时器是不会执行。因为isLighted()中返回的false,


对于你上面的解释我还是有疑惑,在路线加载时,当加载到那四条不受灯控制的的路线时即:S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);他们的lighted此时的值都是true,可是为什定时器此时不移除对应的路线上的车?而是等待LampControl类指定那个S2N的灯亮才运行?
回复 使用道具 举报
1,至于为什么每次都是S2N先通行,这两句代码应该可以解释了,currentlamp=Lamp.S2N;     currentlamp.light();   你在new LampControl();的时候,默认的是先初始化了S2N(N2S)这两条路,其实你也可以改一下,但要是【S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false)】这四条中的一条,因为他们控制着这个路口的循环变向。
2,main函数创建完所有的线程后,也就是创建了12条路,此时,每条路会依据该语句(boolean lighted = Lamp.valueOf(Road.this.name).isLighted();)来判断该路的等是否绿了,如视频所讲,那四条向右的路是一直绿的。
3,至于这个问题“主函数的线程是按顺序执行的,按理说应该先创建完所有的路线,(此时那四条路线已经存在,并且lighted为true,此时可以进行remove()方法了呀。)”,主函数搞了12条路后,每条路的remove方法是要根据“boolean lighted = Lamp.valueOf(Road.this.name).isLighted();”来判断的。所以,即便没有new LampControl();只有那四条向右的路,他们也会一直运行的。(这个你可以修改主函数测试。)
4
,“灯的控制器是怎么样控制路灯的变化的?是必须有它才能开启整个交通灯系统的运作吗? ”,这个问题,准确的来说,控制器是控制那8条主路的。8条主路的通行需要控制器来激活一个主方向(4个中的一个),然后他们循环将lighted置为true,控制方向,4条向右的不受控制器控制。这点你要仔细的理解Lamp这个枚举类,这点是关键,还有,再仔细的看看视频会好点。

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
1、首先我要回答的是,程序是自上而下,顺序执行。
2、我们来分析下,main()这个类,这个类先是产生12条路线,也就是new Road()。你可以一步步分析下,new road(),只是将路线加进了private List<String> vechicles = new ArrayList<String>()这个集合中,而下面的那个定时器是不会执行。因为isLighted()中返回的false,(boolean默认值就是false,这个你知道吧)。
3、执行完了加载路线后,在执行到        new LampController();此时,程序中定义好了初始枚举实例,就是S2N。并且给其isLight赋值为true。也就是你上面提的迷惑。默认初始化实例是S2N,然后每隔10秒后,定时器执行一次,那么当然每次都是: S2N  Lamp is green!下面将会有六个方向的车可以通行!
4、其实,你慢慢去理解下程序运行的原理,估计就不回迷惑了。
5、希望我的回答能给你一些帮助。

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马