黑马程序员技术交流社区

标题: 守护线程的问题(已解决) [打印本页]

作者: 杨锦    时间: 2012-8-3 19:40
标题: 守护线程的问题(已解决)
本帖最后由 杨锦 于 2012-8-4 12:38 编辑

class Test{

public static void main(String[] args) {
  Thread t1 = new Thread(){
   public void run() {
    for (int i = 1; i <= 5; i++) {
     System.out.println("A " + i);
     try {
      Thread.sleep(1000);   
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  };
  
  Thread t2 = new Thread(){
   public void run() {
    for (int i = 1; i <= 10; i++) {
     System.out.println("B " + i);
     try {
      Thread.sleep(1000);   
     } catch(Exception e) {
      e.printStackTrace();
     }
    }
   }
  };
  
  t2.setDaemon(true);  
  t1.start();
  t2.start();
}

}

守护线程B不是应该随着A的结束而结束吗,为什么最后又打了个6出来????

1.jpg (20.5 KB, 下载次数: 12)

1.jpg

作者: 朱烈葵    时间: 2012-8-3 20:11
代码不全吧
作者: 官文昌    时间: 2012-8-3 20:19
这是线程啊,线程会抢cpu资源啊,你又没有加锁,你把你睡的时间该成10ms,你看到结果你就知道了,抢资源是随机性的,当你线程1抢到cpu资源,线程1判断完表达时,开始要执行输出语句了,这时候cpu资源被线程2抢到了,线程2就执行,这时候线程1还没结束嘛,线程2就继续执行,执行到某一时刻时,线程1抢到了资源,线程1执行结束,这时候线程2才会结束,你把你的睡的时间变成10ms,你就相同,当你没加锁的时候,线程不一定是线程1执行了再执行线程2再执行线程1,它们两个是抢资源的~~~~
作者: 王晓龙    时间: 2012-8-3 23:32
lz说的有理啊
作者: 王晓龙    时间: 2012-8-3 23:32
ls 说的有理
作者: 瞿乐    时间: 2012-8-4 02:28
官文昌 说的有点道理。因为你没有加锁,t1和t2两个线程开启后都会抢夺CPU资源。前面10次打印会是1122334455.到了第六次时候,t1和t2进入循环(不能确定顺序,取得执行权才会执行的),进入循环后,可能会是t2抢到了执行权,然后打印了B 6,也可能是t1抢到了执行权(如果是t1先抢到的话,就不会答应B 6,这种情况也会有的,亲多十几次可以看到效果)。因为亲是在刚进入循环后马上就打印了,这个时间差很短,在t2打印 B 6 的时候,t1还没有判断循环条件。t2便打印了, 如果 将答应的语句放到,睡眠之后, t1一进入循环 便判断条件,条件不符合,t1循环跳出,不会进入睡眠状态,t1执行完虚拟机退出,t2应该还在睡眠,就退出了,不会打印 B 6了。只可能出现1122334455的结果了。
如果,这个程序理清两点,就很好理解了。第一:循环条件是在什么时候判断。(在进入循环体一开始就判断了)。第二:当正在运行的线程都是守护线程时,Java 虚拟机退出。(程序中,t1运行完时候,主函数肯定早就运行完了,剩下只有守护线程t2了)。
希望我的回答对亲能有帮助~~
作者: 瞿乐    时间: 2012-8-4 02:29
第一次答题,呵呵
作者: 胡文凡    时间: 2012-8-4 09:31
守护进程在主线程结束时自动结束。
楼主的这个疑问是由线程t1睡眠造成。t1调用打印方法后。进入睡眠,主线程还没有结束。当然t2得到执行一次。如果想这样这样加个判断。就能看出问题的原因来了。
package what;

import java.util.Scanner;

public class DoubleText {
        public static void main(String args[]){
                Scanner in = new Scanner(System.in);
        }
        public static double getDouble(String input,double min,double max){
                return 0.1;
        }
}
class Test{

        public static void main(String[] args) {
          Thread t1 = new Thread(){
           public void run() {
            for (int i = 1; i <= 5; i++) {
             System.out.println("A " + i);
             if(i==5){                                                        //当运行到条件结束时,直接调用系统退出,不执行睡眠。守护线程跟着结束。就不会打印B 6了                           
                     System.exit(1);
                    }
             try {
              Thread.sleep(1000);   
             } catch(Exception e) {
              e.printStackTrace();
             }
            }
           }
          };
         
          Thread t2 = new Thread(){
           public void run() {
            for (int i = 1; i <= 10; i++) {
             System.out.println("B " + i);
             try {
              Thread.sleep(1000);   
             } catch(Exception e) {
              e.printStackTrace();
             }
            }
           }
          };
         
          t2.setDaemon(true);
          t1.start();
          t2.start();
         
        }

        }
运行结果:
A 1
B 1
A 2
B 2
A 3
B 3
B 4
A 4
A 5
B 5





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