黑马程序员技术交流社区

标题: 老毕的视频第十二天中关于停止线程的问题 [打印本页]

作者: 海之波    时间: 2013-12-23 13:23
标题: 老毕的视频第十二天中关于停止线程的问题
为什么下面的程序主线程打印完了(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);
                }
        }
}

作者: taoge    时间: 2013-12-23 13:40
  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. }
复制代码

作者: Kyle    时间: 2013-12-23 13:43
本帖最后由 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. }
复制代码


作者: 海之波    时间: 2013-12-23 13:47
本帖最后由 海之波 于 2013-12-23 13:51 编辑
taoge 发表于 2013-12-23 13:40

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

楼上应该是正解,计算机运算太快了,之前还没发现,我每次运行时都输出的不同结果
作者: 776699    时间: 2013-12-23 14:15
本帖最后由 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);

                }


作者: 任亚俊    时间: 2013-12-23 14:52
同意楼上观点,问题主要出在num++上,与计算机运行速度和多线程交互没有多大关系,当num打印为59时,下一次循环中,先进行判断,59==60是false,然后再加1,所以打印为60后,还要进行一次循环才能停止,只要把num++改为++num就能实现你想要的效果了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2