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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© pzfpang449 中级黑马   /  2013-2-7 10:13  /  1725 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Threads1 {
    int x = 0;

    public class Runner implements Runnable {
        public void run() {
            int current = 0;
            for (int i = 0; i < 4; i++) {
                current = x;
                System.out.println(current + ", ");
                x = current + 2;
            }
        }
    }

    public static void main(String[] args) {
        new Threads1().go();
         
    }

    public void go() {
        Runnable r1 = new Runner();
        new Thread(r1).start();
        new Thread(r1).start();
    }
}

我认为运行结果是0,2,4,6,8,10,12但是我的机子上跑出来是0,2,4,6,0,2,4,6,有人能告诉我应该怎么样去正确地理解这段代码么,不是只有一个Thread1对象么
threadjava

7 个回复

倒序浏览
呵呵,我来帮你分析下吧,首先,你的这个程序是有2个线程在跑,一个是Thread1,还1个是main线程,不过main线程是为了执行Thread而执行的,所以真正功能性的线程是Thread1,start方法是启动线程。并调用run方法,你现在用2个Thread(r1).start()方法,JVM执行的意思是执行完第一个之后是重新执行第二个,而不是紧跟着第一个后面执行,所以结果是0,2,4,6,0,2,4,6,

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
你觉得这样如何:

public class Threads1 {

    public static class Runner implements Runnable {
        public void run() {
                        int x = 0;
            while (true) {
                               
                                System.out.println(x);
                                x+=2;
                                if(x == 100)
                                        break;
            }
        }
    }

    public static void main(String[] args) {
       Runner run = new Runner();
           Runner run1 = new Runner();
           new Thread(run).start();
           new Thread(run1).start();
         
    }

   
}
回复 使用道具 举报
本帖最后由 谢波 于 2013-2-7 15:05 编辑


还真是啊 , 学习了
回复 使用道具 举报
按楼主的代码多运行几次就会有不同的结果 我的机子上 如下
E:\java0217\practice2>java Threads1
0, 0, 2, 2, 4, 4, 6, 6,
E:\java0217\practice2>java Threads1
0, 2, 4, 6, 0, 2, 4, 6,

这是因为第二个线程还没等第一个线程执行完 把x的值重新写回主函数的x中时,第二个线程已经调用了主函数的最初的x值。
所以代码可以这样写
  1. public class Threads1 {
  2. int x = 0;


  3. public class Runner implements Runnable {
  4. public void run() {
  5. int current;
  6. for (int i = 0; i < 4; i++) {
  7. current = x;
  8. System.out.print(current + ", ");
  9. x = current + 2;
  10. }
  11. }
  12. }

  13. public static void main(String[] args) {
  14. new Threads1().go();

  15. }

  16. public void go() {
  17. Runnable r1 = new Runner();
  18. Thread t1 = new Thread(r1);
  19. Thread t2 = new Thread(r1);
  20. t1.start();
  21. try
  22. {
  23. t1.join();
  24. }
  25. catch (Exception e)
  26. {
  27. }//等带线程t1执行完以后再去执行t2  就会得到楼主想要的结果
  28. t2.start();

  29. }
  30. }
复制代码
得到的输出为 0, 2, 4, 6, 8, 10, 12, 14,

回复 使用道具 举报
谢波 发表于 2013-2-7 12:33
楼主,其实一楼的回答呢不对
1,new Thread就开启一个线程,所以,表面上看有3个线程,main ...

讨论下,我少打了个r。你说的3个线程也没错,new Thread是新开一个线程,你看他的是new Thread(r1),2个一样的,是新开了2个,但对象是一样,后面一个相当与,前面执行了再重新开启调用。
回复 使用道具 举报
钱志新 发表于 2013-2-7 14:03
讨论下,我少打了个r。你说的3个线程也没错,new Thread是新开一个线程,你看他的是new Thread(r1),2个 ...

重新调用的X是外部类的一个变量, 如果第一个线程run()方法执行完毕 方法中run的值会写回外部类的x的, 然后第二个线程再次调用外部类的X  所以说 重点不在这,应该是 还没等第一个线程写回X,第二个线程就又一次调用了外部类的X  ,  解决的方法就是先让第一个线程之心完毕写回x后 再让第二个线程调用这个x  这样就能够得到楼主想要的结果了
回复 使用道具 举报
本帖最后由 黄成超 于 2013-2-7 20:31 编辑

这个题目我也运行了几遍,开始的时候在网吧,通过Ediplus+Dos中运行的,开始出现的结果就像楼主说的那样:0,2,4,6,8,10,12,14.开始没怎么想,看到跟楼主说的结果不同,以为哪里出现了问题,后面回去之后又用Myeclipse运行而来几遍,开始的时候出现的结果与上面的相同,后面又出现了0,2,4,6,0,2,4,6等不同结果。仔细想想,确实,每个答案都有他的道理。现在分析一下,首先,这个程序中有3个线程,分别是主线程以及go方法中的两个线程,每new 一个Thread,就是在创建一个线程,输出结果,主要取决于go方法中的两个线程中运行慢的一个线程在开始运行时X的值。x为两个线程所共享!因为两个线程运行快慢无法预知,所以出现的结果也就无法确定,因而会有后面不同的结果。
最后,请老师加分!谢谢!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马