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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

为什么下面的程序主线程打印完了(main....60)后还要打印(Thread-1...run)和(Thread-0...run),主线程打印了(main....60)不是可以直接循环的吗,然后判断的吗,这样flag已经为false了为什么还打印了(Thread-1...run)和(Thread-0...run)?
class StopThread implements Runnable
{
        private boolean flag=true;
        public void run()
        {
                while (flag)
                {
                        System.out.println(Thread.currentThread().getName()+"...run");
                }
        }
        public void changeFlag()
        {
                flag=false;
        }
}
class  StopThreadDemo
{
        public static void main(String[] args)
        {
                StopThread st=new StopThread();
                Thread t1=new Thread(st);
                Thread t2=new Thread(st);
                t1.start();
                t2.start();
                int num=0;
                while (true)
                {
                        if (num++==60)
                        {
                                st.changeFlag();
                                break;
                        }
                        System.out.println(Thread.currentThread().getName()+"...."+num);
                }
        }
}

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

6 个回复

倒序浏览
  1. class StopThread implements Runnable
  2. {
  3.       //这里改为false就可以了,boolea类型初始时都是false
  4.         private boolean flag = false;

  5.         public void run()
  6.         {
  7.                 while (flag)
  8.                 {
  9.                         System.out.println(Thread.currentThread().getName() + "...run");
  10.                 }
  11.         }

  12.         public void changeFlag()
  13.         {
  14.                 flag = false;
  15.         }
  16. }

  17. class StopThreadDemo
  18. {
  19.         public static void main(String[] args)
  20.         {
  21.                 StopThread st = new StopThread();
  22.                 Thread t1 = new Thread(st);
  23.                 Thread t2 = new Thread(st);
  24.                 t1.start();
  25.                 t2.start();
  26.                 int num = 0;
  27.                 while (true)
  28.                 {
  29.                         if (num++ == 60)
  30.                         {
  31.                                 st.changeFlag();
  32.                                 break;
  33.                         }
  34.                         System.out.println(Thread.currentThread().getName() + "...." + num);
  35.                 }
  36.         }
  37. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 Kyle 于 2013-12-23 13:50 编辑

因为计算机的运算速度非常快,当main方法正要将flag设置成false的这段时间内(时间对我们来说非常短,但对计算机来说很长),Thread-1和Thread-0的启动已经开始了,所以当main方法中将flag设置结束的时候,Thread-1和Thread-0也输出了run,然后再启动线程的时候才得到flag已经被设置成false的提示。
同时还发现程序有一个小问题,你用的是num++来作为判定条件的,也就是说当num=59的时候,num++ == 60不满足条件,但下文输出num值的时候num变成了60输出,再走一次循环判定的时候,num才满足条件。 所以不管怎么样,都会先输出60,然后又输出两次线程的run.

  1. package com.eclipse;

  2. class StopThread implements Runnable {
  3.         private boolean flag = true;

  4.         public void run() {
  5.                 while (flag) {
  6.                         System.out.println(Thread.currentThread().getName() + "...run");
  7.                 }
  8.         }

  9.         public void changeFlag() {
  10.                 flag = false;
  11.         }
  12. }

  13. class StopDemo {
  14.         public static void main(String[] args) {
  15.                 StopThread st = new StopThread();
  16.                 Thread t1 = new Thread(st);
  17.                 Thread t2 = new Thread(st);
  18.                 t1.start();
  19.                 t2.start();
  20.                 int num = 0;
  21.                 while (true) {
  22.                         if (num++ == 60) { //当循环走到此处时,线程暂时停在到这,因为线程是交替执行的,所以此时t1,t2可能启动了线程
  23.                                 st.changeFlag();//此时flag才被设置为false
  24.                                 break;
  25.                         }
  26.                         System.out.println(Thread.currentThread().getName() + "...." + num);
  27.                 }
  28.         }
  29. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 海之波 于 2013-12-23 13:51 编辑

嗯,知道,但是主线程中if语句判断num=60后,接着flag就为false了,也就是说主线程结束后flag就为false,当线程t1和t2运行做while判断的时候flag已经为false了,那么当main。。。60打印完了,为什么还要打印t1和t2中的内容
回复 使用道具 举报
海之波 发表于 2013-12-23 13:47
嗯,知道,但是主线程中if语句判断num=60后,接着flag就为false了,也就是说主线程结束后flag就为false, ...

楼上应该是正解,计算机运算太快了,之前还没发现,我每次运行时都输出的不同结果
回复 使用道具 举报
本帖最后由 776699 于 2013-12-23 14:19 编辑

运行时:每次执行三个线程,main ,t1,t2,。但约束条件为main,所以当main中 的if条件num=60时,num++:为先赋值,后f加1;所以当num=61·时,flag才被设置为false,剩下两个线程为假,break 结束前,num=61;你可以syso测试一下。
fif (num++ == 60) {
                                st.changeFlag();//此时flag才被设置为false

                                break;

                        }

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

                }

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报 1 0
同意楼上观点,问题主要出在num++上,与计算机运行速度和多线程交互没有多大关系,当num打印为59时,下一次循环中,先进行判断,59==60是false,然后再加1,所以打印为60后,还要进行一次循环才能停止,只要把num++改为++num就能实现你想要的效果了。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

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