黑马程序员技术交流社区

标题: 停止线程特殊情况的问题 [打印本页]

作者: 龚振 龚振 龚振    时间: 2012-4-11 19:43
标题: 停止线程特殊情况的问题
在day12里StopThrea停止线程特殊情况如下,为什么加了synchronizedvoid,和wait()后线程1,2就不能停下来了?
主线程结束了线程就不能运行了吗?
如果两个线程被wait后,一段时间醒来再判断flag为false时应该就可以结束了呀。怎么回事呢?
  1. class StopThread implements Runnable
  2. {
  3.         private boolean flag =true;
  4.         public [color=Red]synchronizedvoid[/color] run()
  5.         {
  6.                 while(flag)
  7.                 {
  8.                         try
  9.                         {
  10.                                 [color=Red]wait();[/color]
  11.                         }      
  12.                         catch(InterruptedException e)
  13.                         {
  14.                              System.out.println(Thread.currentThread().getName()+"....Exception");
  15.                         }
  16.                         System.out.println(Thread.currentThread().getName()+"....run");
  17.                 }
  18.         }
  19.         public void changeFlag()
  20.         {
  21.                 flag = false;
  22.         }
  23. }

  24. class  StopThreadDemo
  25. {
  26.         public static void main(String[] args)
  27.         {
  28.                 StopThread st = new StopThread();
  29.                
  30.                 Thread t1 = new Thread(st);
  31.                 Thread t2 = new Thread(st);
  32.    
  33.                 t1.start();
  34.                 t2.start();

  35.                 int num = 0;

  36.                 while(true)
  37.                 {
  38.                         if(num++ == 60)
  39.                         {
  40.                                 st.changeFlag();
  41.                                 break;
  42.                                
  43.                         }
  44.                         System.out.println(Thread.currentThread().getName()+"......."+num);
  45.                 }
  46.                 System.out.println("over");
  47.         }
  48. }
复制代码

作者: 薛飞飞    时间: 2012-4-11 20:22
while(flag){

                try{

                       wait();---------------->线程已开启,因为flag是true,所以线程会执行wai()语句,从而一直等待在这里,因此它不会再去执行while(flag)判断条件语句,所以你改不改变flag的值,对线程都没有影响,两个线程会一直处于等待状态,从而导致进程不会终止

                }catch(InterruptedException e) {

                       System.out.println(Thread.currentThread().getName()+"....Exception");
                 }
                System.out.println(Thread.currentThread().getName()+"....run");
}


作者: 未长法    时间: 2012-4-11 20:24
线程t1 和线程t2 开启后,只要抢到cpu 执行权就会去执行run()方法,t1 进来拿到锁 判断flag后wait()  冻结释放资源 ,这时t2也进来拿到锁 判断flag后 也wait()冻结释放了资源。当线程处于了冻结状态时,就不会读取到标记,那么线程就不会结束。
因此当主线程运行完以后,改变Flag ,但是t1 和t2 读不到标记因此线程不会结束
作者: 未长法    时间: 2012-4-11 20:36
当没有指定的方式让冻结状态恢复到运行状态时,就需要对冻结状态进行清除。Interrupt();
class StopThread implements Runnable

{

        private boolean flag =true;

        public synchronizedvoid run()

        {

                while(flag)

                {

                        try

                        {

                                wait();

                        }      

                        catch(InterruptedException e)

                        {

                             System.out.println(Thread.currentThread().getName()+"....Exception");
                             flag=false;

                        }

                        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)

                        {

                                t1.interrupt();
                                 t2.interrupt();
                                break;

                                
                        }

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

                }

                System.out.println("over");

        }

}
作者: 金兴    时间: 2012-4-11 20:39
因为当你引入synchronized 后,在java中使用synchronized关键字来标识被同步的资源,在需要同步操作程序代码前加上synchronized标记,这样的代码又被称为同步代码块,则线程间需要同步.这样的话,只有当一个线程运行完这段代码块后,其他线程才可以进入运行.当你调用wait()方法后,调用notify()唤醒它,在睡眠之前,线程会释放掉所占有的"锁标识",则其占用的所有synchronized 代码块可被别的线程使用.
作者: 龚振 龚振 龚振    时间: 2012-4-11 20:44
谢谢两位,还有一点没清楚,比如说wait(10)后,线程10毫秒过后不是醒过来了吗
wait()后不能自己醒过来么?
如果可以的话,然后应该执行
System.out.println(Thread.currentThread().getName()+"....Exception");
System.out.println(Thread.currentThread().getName()+"....run");
然后判断标记非false就停止了
第二个线程也如此
不就O了吗?
开始懂了,现在看是糊涂了{:soso_e134:}

作者: 赵云柯    时间: 2012-4-12 14:18
线程遇到wait()后会一直等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,该线程才会被唤醒。wait()状态的线程是不能自己醒来的。




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