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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王晓新 中级黑马   /  2012-6-20 16:40  /  1727 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王晓新 于 2012-6-21 09:14 编辑
  1. public class Road {
  2.         List<String> cars = new ArrayList<String>();
  3.         private String name=null;
  4.         public Road(String name){
  5.                 this.name=name;
  6.                 //这里是采用了线程池,当有任务进来时,执行器将任务交给线程池,再由线程池去决定到底使用哪个线程去解决问题
  7.                 ExecutorService pool = Executors.newSingleThreadExecutor();//返回的就是一个线程池,为什么选择这个newSingleThreadExecutor()?
  8.                 pool.execute(new Runnable(){//执行任务
  9.                         public void run(){
  10.                                 for(int i=1;i<1000;i++){
  11.                                         try {
  12.                                                 Thread.sleep((new Random().nextInt(10)+1)*1000);//
  13.                                         } catch (InterruptedException e) {
  14.                                                 e.printStackTrace();
  15.                                         }
  16.                                         cars.add(Road.this.name+"_"+i);//访问外部内的成员变量,如果是this.name是不是就是说这个name是Runnable类的变量呢?要访问Road类的name就必须是Road.this.name?这里有点迷糊了
  17.                                 }
  18.                         }
  19.                 });               
  20.         }
  21. }
复制代码

8 个回复

倒序浏览
本帖最后由 李天甲 于 2012-6-20 17:01 编辑

呵呵,您上面写的外部内是什么?
1  访问内部类的成员变量,如果是this.name是不是就是说这个name是Runnable类的变量呢? 对的

2  要访问Road类的name就必须是Road.this.name?
内部类访问外部类对象的途径是 [外部类类名.this.XXX] 对象获取到之后就可以随意调用外部类的各种成员了。

3 返回的就是一个线程池,为什么选择这个newSingleThreadExecutor()?
因为只要用一个线程生成车辆就行了.你可以想象成双向单车道,双向四车道的话你可以弄四个线程呵呵.但是实现效果没有任何区别,都是在路口堵着等通行信号
回复 使用道具 举报
李天甲 发表于 2012-6-20 16:56
呵呵,您上面写的外部内是什么?
1  访问内部类的成员变量,如果是this.name是不是就是说这个name是Runnable ...

嗯,这个地方理解了,上面那个关于选择哪个线程池的问题还是不清楚
回复 使用道具 举报
王晓新 发表于 2012-6-20 16:58
嗯,这个地方理解了,上面那个关于选择哪个线程池的问题还是不清楚

已经更新呵呵
回复 使用道具 举报
第一个问题其实张老师就是想新启动一个线程而已,你完全可以new Thread().start();
老师的代码在每一次创建Road类的对象的时候都创建了一个新的线程池,这种做法并不好,如果要用线程池,个人以为应该只创建一个固定大小为12,或者是可变长度的线程池,解决方法有多样,可以再Road类中保存线程池的引用,在static代码块中new出线程池的对象,也可以通过构造方法在外部传对象,甚至可以通过set方法等。

第二个问题,就是区分name ,this.name  ,Road.this.name代表的是什么
如果你写name,虚拟机先找局部变量看有没有name,没有,会去类的成员变量里面找有没有this.name,如果没有,这个类的外部类中找成员变量,这个成员变量就是Road.this.name了。如果还没有,继续往上级找,找到为止。
回复 使用道具 举报
闾丘日月 发表于 2012-6-20 17:04
第一个问题其实张老师就是想新启动一个线程而已,你完全可以new Thread().start();
老师的代码在每一次创建 ...

解释的清晰。。。:handshake
回复 使用道具 举报
闾丘日月 发表于 2012-6-20 17:04
第一个问题其实张老师就是想新启动一个线程而已,你完全可以new Thread().start();
老师的代码在每一次创建 ...

嗯,解释的不错,赞一个
回复 使用道具 举报
如果内部类和外部类变量重名时,用this.name访问的是内部类的变量,访问外部类的变量需要用 外部类名.this.变量名  来访问外部类的变量 就是你用的Road.this.name
如果内部类和外部类不重名,则可以直接访问外部类的变量 即直接用  name
给你做个小例子理解一下吧:
  1. 输出结果为
  2. 11111
  3. 11111
  4. 1000
  5. 1000
  6. 22222

  7. public class Test {
  8.         private int b=11111;
  9.         private int a=22222;
  10.         public class Test1{
  11.                     private int a=1000;
  12.                     public void outstr(){
  13.                                System.out.println(b);
  14.                                System.out.println(Test.this.b);
  15.                                System.out.println(a);
  16.                                System.out.println(this.a);
  17.                                System.out.println(Test.this.a);
  18.                      }
  19.            }
  20.            public Test1 t=new Test1();
  21.            public static void main(String[] args) {
  22.                       new Test().t.outstr();
  23.            }
  24. }
复制代码

点评

不错不错。。。  发表于 2012-6-20 17:28
回复 使用道具 举报
this代表当前对象。那么你的类也是一个对象,所以(Road.this.name)应该不奇怪吧!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马