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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨锦 中级黑马   /  2012-8-3 19:40  /  2025 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨锦 于 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

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1

查看全部评分

8 个回复

倒序浏览
代码不全吧
回复 使用道具 举报
这是线程啊,线程会抢cpu资源啊,你又没有加锁,你把你睡的时间该成10ms,你看到结果你就知道了,抢资源是随机性的,当你线程1抢到cpu资源,线程1判断完表达时,开始要执行输出语句了,这时候cpu资源被线程2抢到了,线程2就执行,这时候线程1还没结束嘛,线程2就继续执行,执行到某一时刻时,线程1抢到了资源,线程1执行结束,这时候线程2才会结束,你把你的睡的时间变成10ms,你就相同,当你没加锁的时候,线程不一定是线程1执行了再执行线程2再执行线程1,它们两个是抢资源的~~~~

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1

查看全部评分

回复 使用道具 举报
lz说的有理啊
回复 使用道具 举报
ls 说的有理
回复 使用道具 举报
官文昌 说的有点道理。因为你没有加锁,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了)。
希望我的回答对亲能有帮助~~

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1

查看全部评分

回复 使用道具 举报
第一次答题,呵呵
回复 使用道具 举报
守护进程在主线程结束时自动结束。
楼主的这个疑问是由线程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

评分

参与人数 1技术分 +1 收起 理由
包晗 + 1

查看全部评分

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