黑马程序员技术交流社区

标题: 多线程守护线程的问题 [打印本页]

作者: 罗广伟    时间: 2013-6-15 09:41
标题: 多线程守护线程的问题
  1. class Test
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Run r=new Run();
  6.                 Thread t1=new Thread(r);
  7.                 Thread t2=new Thread(r);
  8.                 //t2.setDaemon(true);
  9.                 //t1.setDaemon(true);
  10.                 t1.start();
  11.                 t2.start();
  12. t2.setDaemon(true);
  13. t1.setDaemon(true);
  14.                
  15.                 for(int x=0;x<10;x++)
  16.                 {
  17.                         System.out.println("=");
  18.                 }
  19.                 r.set();
  20.                 System.out.println("over");
  21.         }
  22. }
  23. class Run implements Runnable
  24. {
  25.         private boolean flag=true;
  26.         public synchronized void run()
  27.         {
  28.                 while(flag)
  29.                 System.out.println(Thread.currentThread().getName()+"==gogo");
  30.         }
  31.         public void set()
  32.         {
  33.                 flag=false;
  34.         }
  35.        
  36. }
复制代码
问题位置:多线程12天08,视频中毕老师说setDaemon()需要在线程开启之前设置,这样非守护线程结束,守护线程自行结束。可是当setDadmon()写在线程开启之后只运行t1.t2程序不停止,这是为什么?
作者: 薛淑凯    时间: 2013-6-15 14:25
有没有发现运行时有异常啊,运行太快可能没看到,在运行结果最开始的时候。加个sleep就看到了
Exception in thread "main" java.lang.IllegalThreadStateException
        at java.lang.Thread.setDaemon(Thread.java:1365)
        at Text.main(Text.java:10)

然后setDaemon()方法上写有,该方法必须在启动线程前调用。否则
抛出:
IllegalThreadStateException - 如果该线程处于活动状态。就好像给这个线程加属性,应该在没运行的时候加,运行了就没法改变了
作者: 孙茜茜    时间: 2013-6-15 15:50
异常是穿插着打印出来,我也想知道为什么
D:\javafile\day13>java Tiezi
Exception in thread "main" Thread-0==gogo
Thread-0==gogo
Thread-0==gogo
Thread-0==gogo
Thread-0==gogo
Thread-0==gogo
java.lang.IllegalThreadStateExceptionThread-0==gogo

Thread-0==gogo
        at java.lang.Thread.setDaemon(Thread.java:1365)Thread-0==gogo

        at Tiezi.main(Tiezi.java:16)
Thread-0==gogo

下面疯狂打印Thread-0==gogo
作者: 林森~Linson    时间: 2013-6-15 17:36
这个问题和守护线程的设置没关系,问题在于线程的run()方法中while循环是死循环,而且还没有睡眠,那么Thread-0线程就一直占用run()方法,所以一直是:Thread-0==gogo
这样循环下去。所以应该在while()循环中加入 try{  Thread.sleep(100);}catch(Exception e){},这样其他线程才有机会去调用run()方法。
作者: 王磊    时间: 2013-6-16 03:43
主函数运行后,两个线程开启,这时候无法再设置守护线程。运行结果开头处抛出异常。说明设置失败,并且这两句代码不运行,由于抛出的是Exception,所以不影响主函数运行。
Exception in thread "main" java.lang.IllegalThreadStateException
        at java.lang.Thread.setDaemon(Thread.java:1365)
        at Test.main(1111.java:12)

我改了下两个线程的开启顺序,发现开启t2线程后,运行结果为这个线程无限循环。说明线程开启后,直接运行了一次,线程主体是一个死循环,并且封在同步函数内,所以该线程不执行完,其他线程无法执行。所以先抛出后台线程的设置异常,然后进入单一线程的同步死循环。

个人理解。希望有所帮助。


作者: 王磊    时间: 2013-6-16 03:55
不好意思,刚刚顺手写错了一个地方,就是到在主函数内抛出了异常后,主线程就停止运行,所以后面调用set方法来停止循环的语句就执行不到了。造成了线程的循环。
补充一下,你的这个同步函数内并没有操作共有数据,只是单纯的打印操作。所以我刚刚删除了synchronized关键字,运行一次,除了开始时抛出了后台线程设置的异常外,线程的运行状况正常。说明程序进入死循环,就是因为抛出异常后,主线程不继续运行,执行不到后续的限制条件。

希望能有所帮助
作者: 孙百鑫    时间: 2013-6-22 01:25
楼主您好~帖子长时间未作出回答,我已经将您的帖子改成已解决。如果有问题的话可以私密我哦~




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