黑马程序员技术交流社区

标题: 【多线程(停止线程)】里的一个例子,有个小疑惑 [打印本页]

作者: 王春晓    时间: 2013-4-25 18:15
标题: 【多线程(停止线程)】里的一个例子,有个小疑惑
本帖最后由 王春晓 于 2013-4-25 18:16 编辑

class StopThread implements Runnable
{
        private boolean flag = true;
        public synchronized void run()
        {
                while(flag)
                {
                        try
                        {
                                wait();
                        }
                        catch (InterruptedException e)
                        {
                                System.out.println(Thread.currentThread().getName()+"...Exception");
                        }
                }
        }
        public void changeFlag()
        {
                flag = false;
        }
}

class  StopThreadDemo1
{
        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();
                                t1.interrupt();
                                t2.interrupt();
                                break;
                        }
                        System.out.println(Thread.currentThread().getName()+"......"+num);
                }
        }
}

老毕的视频里的一个例子,我的疑惑是,当红色的语句执行后,绿色while里的flag值是true还是false?为什么?谢谢各路大神!
作者: 殇_心。    时间: 2013-4-25 18:23
false.
因为这个flag是成员变量嘛。
成员函数改变这个flag值是可以的。
作者: 聖手`书生    时间: 2013-4-25 18:48
1.flag是在StopThread类的成员变量,一旦此类被实例化,就存在于堆内存中。
2.changeFlag函数体中的flag = false;相当于this.flag=false;改变flag的值为false。
3.当主程序的线程执行到st.changeFlag();flag为false,run方法中的while循环判断为false,循环结束,也就是run方法结束,run方法结束也就是t1、t2线程结束。
作者: 袁梦希    时间: 2013-4-25 19:10
本帖最后由 袁梦希 于 2013-4-25 19:28 编辑

楼主你好,根据个人的理解
1-----当开启线程的时候t1.start(); t2.start();  t1和t2同时执行run()方法,某个线程先判断锁,然后这个线程执行run方法了,执行到wait()了,让线程等在那里了。
2-----这时候另一个线程获得了执行权,在run方法外面进来了,一判断执行也等在那里了,因为这是个同步函数。
3-----然后main这个主线程开始往下执行,当把1到60个数都执行完以后,两个线程都在wait()那里等着呢,某个线程调用了changeFlag();把true变为了false。
4-----这时候两个线程都等在那里了,然后执行到线程的中断t1.interrupt();t2.interrupt();   两个线程判断run方法的while中的flag为false,结束了线程,抛了异常。
        这时候才把两个线程都打印了。
所以楼主要问的,当两个线程进入while前、进入while后,并且等在里面的时候,绿色的while里面的时候flag为true。
当线程调用中断线程的方法时,肯定为false 。这时候抛异常,也就把异常打印处理。



  1.        package com.xbox;
  2.      class StopThread implements Runnable{
  3.         private boolean flag = true;
  4.         public synchronized void run(){
  5.                 while(flag){
  6.                  
  7.                  System.out.println("while中的flag为"+flag);
  8.                         try{
  9.                          System.out.println(Thread.currentThread().getName());
  10.                                 wait();
  11.                         }
  12.                         catch (InterruptedException e){
  13.                                 System.out.println(Thread.currentThread().getName()+"...Exception");
  14.                         }finally{
  15.                         
  16.                          System.out.println("最后的"+flag);
  17.                          //判断这时候的finally中的flag为false了,可是两个线程早已经执行完事了
  18.                          //因为是两个线程,所以打印两次
  19.                         }
  20.                 }
  21.         }
  22.         public void changeFlag(){      
  23.                 flag = false;
  24.                
  25.         }
  26. }
  27.         class  Test{
  28.         public static void main(String[] args) {
  29.                   StopThread st = new StopThread();
  30.                   Thread t1 = new Thread(st);
  31.                   Thread t2 = new Thread(st);
  32.                   t1.start();//开启线程
  33.                   t2.start();
  34.                   int num = 0;
  35.                  while(true){
  36.                         if(num++ == 60){
  37.                                 st.changeFlag();
  38.                                 t1.interrupt();//中断线程
  39.                                 t2.interrupt();
  40.                                 break;
  41.                         }
  42.                         System.out.println(Thread.currentThread().getName()+"......"+num);
  43.                 }
  44.         }
  45. }
复制代码
希望可以帮到你

作者: 蔚蓝小嗨    时间: 2013-4-25 19:23
绿色while里的flag值是是false,这个应该没什么疑惑的,st调用changeFlag方法,给flag负值false,但是t1,t2线程并没有结束,因为线程处于了冻结状态,不会读到flag这个标记的
作者: 王春晓    时间: 2013-4-25 20:30
蔚蓝小嗨 发表于 2013-4-25 19:23
绿色while里的flag值是是false,这个应该没什么疑惑的,st调用changeFlag方法,给flag负值false,但是t1,t2 ...

谢谢!!
作者: 王春晓    时间: 2013-4-25 20:31
袁梦希 发表于 2013-4-25 19:10
楼主你好,根据个人的理解
1-----当开启线程的时候t1.start(); t2.start();  t1和t2同时执行run()方法,某个 ...

分析的很详细,帮我更深层次的理解了整个程序,十分感谢!!
作者: 王春晓    时间: 2013-4-25 20:32
殇_心。 发表于 2013-4-25 18:23
false.
因为这个flag是成员变量嘛。
成员函数改变这个flag值是可以的。

谢谢您的帮助!
作者: 王春晓    时间: 2013-4-25 20:32
聖手`书生 发表于 2013-4-25 18:48
1.flag是在StopThread类的成员变量,一旦此类被实例化,就存在于堆内存中。
2.changeFlag函数体中的flag =  ...

分析很详细,谢谢!
作者: 黄玉昆    时间: 2013-4-26 23:40
如果问题已解决,请将分类改为已解决,谢谢




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