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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 莫道荣 中级黑马   /  2013-3-17 23:19  /  1780 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 莫道荣 于 2013-3-18 20:54 编辑

  1. package org.credo.thread;
  2. public class FirstRunnable implements Runnable{
  3. private int i;
  4. public void run(){
  5.      for(;i<10;i++){

  6.             //当线程类实现Runnable接口时,

  7.             //如果想获取当前线程,只能用Thread.currentThread()方法.

  8.             System.out.println(Thread.currentThread().getName()+" "+i);

  9.         }

  10.     }
  11.     public static void main(String[] args) {

  12.         for(int i=0;i<10;i++){

  13.             System.out.println(Thread.currentThread().getName()+" "+i);

  14.             if(i==2){

  15.                 FirstRunnable fr=new FirstRunnable();

  16.                 //通过new Thread(target,name)方法创建新线程

  17.                 new Thread(fr,"newThread11").start();

  18.                 new Thread(fr, "newThread22").start();

  19.             }

  20.         }

  21.     }

  22. }
  23. 输出:
  24. main 0
  25. main 1
  26. main 2
  27. main 3
  28. main 4
  29. newThread11 0
  30. newThread22 0
  31. newThread22 2
  32. main 5
  33. main 6
  34. main 7
  35. main 8
  36. main 9
  37. newThread22 3
  38. newThread22 4
  39. newThread11 1
  40. newThread11 6
  41. newThread22 5
  42. newThread11 7
  43. newThread22 8
  44. newThread11 9
  45. 输出让我有点额...不太理解,就那两个0....按理说应该是1,2线程都是0~9顺序的.
  46. 按理来说,i应该是连续的,也就是采用runnable接口的方式创建的多个线程可以共享线程类的实例属性.这是因为在这种方式下,程序所创建的Runnable对象只是线程的target,而多个线程可以共享同一个target,所以多个线程可以共享同一个线程类(实际上应该是线程的target类)的实例属性.

  47. 所以,很是不解,求解释了......高手.
复制代码

点评

再次提醒: 如果问题未解决,请继续追问回复者,如果问题已经解决,请将分类改为“已解决”,否则将扣除技术分,谢谢  发表于 2013-3-18 12:11
如果问题未解决,请继续追问回复者,如果问题已经解决,请将分类改为“已解决”,谢谢  发表于 2013-3-18 06:06

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

4 个回复

倒序浏览
1.多个线程确实可以共享target类的实例变量,你的例子已经告诉你这个事实了
2.至于为什么输出两个0,就是因为多个线程共享了该变量,而你这里的代码没有对 i 进行同步,所以就会出现相同值的问题啦
回复 使用道具 举报
我试了一下,你的代码,没有问题啊,跟你说的输出结果,完全不一样。你再检查一下。我的输出结果如下:

main 1
main 2
newThread11 0
newThread11 1
newThread11 2
newThread11 3
newThread11 4
newThread11 5
newThread11 6
newThread11 7
newThread11 8
newThread11 9
main 3
main 4
main 5
main 6
main 7
main 8
main 9
回复 使用道具 举报
本帖最后由 谢洋 于 2013-3-18 00:11 编辑

05.public void run(){
06.     for(;i<10;i++){
08.            //当线程类实现Runnable接口时,

10.            //如果想获取当前线程,只能用Thread.currentThread()方法.
                //线程2先是挂在这,
12.            System.out.println(Thread.currentThread().getName()+" "+i);//i为两线程共享,当线程1刚好执行完这一句,还未来得及执行 i++线程2又执行到了这里,
                注意:i++是循环后才执行的,就说线程1第一次执行,还没执行完,i还是0,这时线程2第一次又来,所以他第一来遇的i也是0
               所以除了0可能出现两次,其他数字即不使同步也不会出两次,但可能有个别数字没有被找打印
14.        }

16.    }

评分

参与人数 1技术分 +1 收起 理由
贾文泽 + 1

查看全部评分

回复 使用道具 举报
public class FirstRunnable implements Runnable{

private int i;

public void run(){

     for(;i<10;i++){



            //当线程类实现Runnable接口时,



            //如果想获取当前线程,只能用Thread.currentThread()方法.



            System.out.println(Thread.currentThread().getName()+" "+i);



        }



    }

    public static void main(String[] args) {



        for(int i=0;i<10;i++){



            System.out.println(Thread.currentThread().getName()+" "+i);



            if(i==2){



                FirstRunnable fr=new FirstRunnable();



                //通过new Thread(target,name)方法创建新线程



                new Thread(fr,"newThread11").start();



                new Thread(fr, "newThread22").start();



            }



        }
我的运行结果:
main 0
main 1
main 2
newThread11 0
main 3
newThread22 1
newThread11 1
newThread22 2
main 4
newThread22 4
newThread11 3
newThread22 5
main 5
newThread22 7
newThread11 6
newThread22 8
main 6
newThread11 9
main 7
main 8
main 9
程序开始只有主线程在运行,打印0,1,2
i=2  创建Runable的子类对象,开启了两个线程,cup在 主线程,Thread11,Thread22,之间切换执行。
下面是用匿名内部类创建线程:
                new Thread("t1"){
                        public void run(){
                                for(int i=0;i<6;i++){
                                        System.out.println(getName());
                                        try{
                                                Thread.sleep(100);
                                        }catch(Exception e){
                                                e.printStackTrace();
                                        }
                                       
                                }
                               
                        }
                       
                };
               
               
                new Thread(new Runnable(){
                        public void run(){
                                for(int x=0; x<3; x++){
                                        System.out.println(Thread.currentThread().getName());
                                        try{
                                        Thread.sleep(100);
                                        }catch(Exception e){
                                                e.printStackTrace();
                                        }
                                        }
                                }
                               
                },"T2").start();
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马