网上的资料中,守护线程的功能一般都是“只要当前JVM实例中尚存任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束是,守护线程随着JVM一同结束工作,Daemon作用是为其他线程提供便利服务,守护线程最典型的应用就是GC(垃圾回收器),他就是一个很称职的守护者。”

可是,我发现真实情况却不是描述的这么回事,因为我对java也不懂,所以在此记录一下守护线程中的一些问题。

我的思路是:

在main线程中建立两个线程,一个线程A只打印一行信息就退出,它被设置成守护线程,另一个线程B通过sleep和循环来进行时间控制,让它多运行一会,他被设置成非守护线程。如果按照上面的说明,我认为线程A怎么说也要和线程B的消亡时间是一样的。实际情况却不是这样的。

下面是代码:

文件 ThreadDaemon.java

packagejavaStudy.threadStudy;importjava.util.Date;public classThreadDaemon {public static voidmain(String[] args) {//Thread.currentThread().setDaemon(true);//Thread.currentThread().start();//系统的main函数使用一个主线程,主线程不是守护线程,也不能被设置成守护线程

System.out.println(Thread.currentThread().getName() + "\tprocess begin\t" + (new Date()) + "\t"

+ Thread.currentThread().isDaemon() + "\tthread amount\t"

+Thread.currentThread().getThreadGroup().activeCount());

showThreadName();//新建一个线程,并将其设置成守护线程,他的操作仅仅是打印一行信息。

Thread t = newThread(ThreadDaemon::daemonPrint);

t.setDaemon(true);

t.start();

System.out.println(Thread.currentThread().getName()+ "\tafter create thread A\t" + (new Date()) + "\t"

+ Thread.currentThread().isDaemon() + "\tthread amount\t"

+Thread.currentThread().getThreadGroup().activeCount());

showThreadName();//再建立一个线程,将其设置成用户线程,即非守护线程。让他多执行一会。

try{

Thread.sleep(1000 * 3);

Thread thread2= newThread(ThreadDaemon::print);

thread2.setDaemon(false);

thread2.start();

System.out.println(Thread.currentThread().getName()+ "\tafter create thread B\t" + (new Date()) + "\t"

+ Thread.currentThread().isDaemon() + "\tthread amount\t"

+Thread.currentThread().getThreadGroup().activeCount());

showThreadName();

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+ "\tExit:" + "\t" + (new Date()) + "\t"

+ Thread.currentThread().isDaemon() + "\tthread amount "

+Thread.currentThread().getThreadGroup().activeCount());

showThreadName();//System.exit(0) 是退出jvm。如果有此代码,则子线程也会直接随着主线程而退出。如果没有此代码,jvm会在子线程结束的时候而退出。//System.exit(0);

}//用户线程的调用

public static voidprint() {int counter = 1;while (counter < 5) {try{

Thread.sleep(3 * 1000); //sleep for 10 seconds

System.out.println(Thread.currentThread().getName() + "\tbefore Counter:" + counter++ + "\t"

+ (new Date()) + "\t" + Thread.currentThread().isDaemon() + "\tthread amount "

+Thread.currentThread().getThreadGroup().activeCount());

Thread.sleep(3 * 1000); //sleep for 10 seconds

System.out.println(Thread.currentThread().getName() + "\tafter Counter:" + counter++ + "\t"

+ (new Date()) + "\t" + Thread.currentThread().isDaemon() + "\tthread amount "

+Thread.currentThread().getThreadGroup().activeCount());

showThreadName();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}//守护线程的调用

public static voiddaemonPrint() {try{

Thread.sleep(6 * 1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(

Thread.currentThread().getName()+ "\t" + (new Date()) + "\t" +Thread.currentThread().isDaemon()+ "\tthread amount " +Thread.currentThread().getThreadGroup().activeCount());

showThreadName();

}//显示线程名称

public static voidshowThreadName() {

ThreadGroup currentGroup=Thread.currentThread().getThreadGroup();int noThreads =currentGroup.activeCount();

Thread[] lstThreads= newThread[noThreads];

currentGroup.enumerate(lstThreads);for (int i = 0; i < noThreads; i++) {

System.out.println("==============="+lstThreads[i].getName() + "\t" +lstThreads[i].isDaemon());

}

}

}

以上代码,我根据程序休眠的时间,让主线程先退出,然后发现守护线程却在第二个退出的。因为他不是死循环,所以提前退出了?这么说来,如果一个线程要想是守护线程的话,他必须是死循环?也就是说,从程序表面看,守护线程一定要比用户线程存活的久一点?这么说来,将一个理论上活的更久的线程,设置成守护线程,仅仅是让它自动和用户线程一起消亡罢了。实际上,通过延长上面代码的daemonPrint()的sleep的时间,也可以验证守护线程会和用户线程一起消亡。

下面是程序的日志:

main process begin Tue Oct 16 17:17:29 CST 2018 false thread amount 1

===============mainfalse

mainafter create thread ATue Oct 16 17:17:30 CST 2018falsethread amount2

===============mainfalse

===============Thread-0true

mainafter create thread BTue Oct 16 17:17:33 CST 2018falsethread amount3

===============mainfalse

===============Thread-0true

===============Thread-1false

mainExit:Tue Oct 16 17:17:33 CST 2018falsethread amount 3

===============mainfalse

===============Thread-0true

===============Thread-1false

Thread-0Tue Oct 16 17:17:36 CST 2018truethread amount 3

===============Thread-0true// 这一行日志,说明他是守护线程,但是下面却没有了他的名字。因为他不是死循环,所以提前退出了?

===============Thread-1false

===============DestroyJavaVMfalse

Thread-1before Counter:1Tue Oct 16 17:17:36 CST 2018falsethread amount 2

Thread-1after Counter:2Tue Oct 16 17:17:39 CST 2018falsethread amount 2

===============Thread-1false

===============DestroyJavaVMfalse

Thread-1before Counter:3Tue Oct 16 17:17:42 CST 2018falsethread amount 2

Thread-1after Counter:4Tue Oct 16 17:17:45 CST 2018falsethread amount 2

===============Thread-1false

===============DestroyJavaVMfalse

结论:代码的逻辑让守护线程提前于用户线程消亡的情况下,守护线程并不会主动延长生命和用户线程一起消亡。但是,代码的逻辑让守护线程延迟于用户线程消亡的情况下,守护线程会提前和用户线程一起消亡。这样也可以理解,毕竟CPU资源那么金贵,既然守护线程提前与用户线程消亡,那他没有必要赖着占用CPU的资源,对吧?

java 守护线程 作用_java中守护线程的一些概念和用法相关推荐

  1. java多线程 线程安全_Java中的线程安全

    java多线程 线程安全 Thread Safety in Java is a very important topic. Java provides multi-threaded environme ...

  2. java 全局变量线程安全_Java中的线程安全全局变量

    我试图了解 java中的线程安全机制,我需要一些帮助.我上课了: public class ThreadSafe { private Executor executor = new Scheduled ...

  3. java finally的作用_java中finally关键字的特点和作用是什么

    java中finally关键字的特点和作用是什么 发布时间:2020-09-08 11:12:01 来源:亿速云 阅读:114 作者:小新 小编给大家分享一下java中finally关键字的特点和作用 ...

  4. java 构造函数的作用_Java中构造函数的作用(转)

    https://blog.csdn.net/vipmao/article/details/51530954,我觉得讲的非常好,学习到了 构造函数的最大作用就是创建对象时完成初始化,当我们在new一个对 ...

  5. java里面序列化作用_java中序列化的作用

    一  什么叫序列化 通俗点讲:它是处理对象流的一种机制,即可以很方便的保存内存中java对象的状态,同时也为了方便传输. 二 序列化有什么作用 1.方便传输,速度快,还很安全,被调用方序列化,调用方反 ...

  6. java throws的作用_Java中throws..throw的使用与说明

    throws语句 throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常.对大多数Exception子类来说,Java 编译器会强迫你声明在一个成员函数中抛出的异常的类型.如果异常的 ...

  7. java comparable接口作用_Java 中 Comparable 接口的意义和用法

    一, 为何需要实现Comparable接口 我们知道Collections类中包含很多对实现Collection接口的容器各种操作的静态方法. 当然, 其中最长用的莫过于排序了(Collections ...

  8. java的rsa作用_java 中RSA的方式实现非对称加密的实例

    java 中rsa的方式实现非对称加密的实例 rsa通俗理解: 你只要去想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密:同理,既然是签名,那肯 ...

  9. java new string作用_java中直接new String对象?

    首先明确一点,在Java中==比较的是两个对象的地址,equals()比较的是两个对象的值,如果使用equals()来替换==,则两个输出结果都为true. 言归正传,为什么第一个返回为false? ...

最新文章

  1. 【神经网络】(13) ShuffleNetV2 代码复现,网络解析,附Tensorflow完整代码
  2. Cinder LVM Oversubscription in thin provisioning
  3. 前端学习(2774):方式1进行路由跳转
  4. Keras:Transfer learning
  5. python epoll 写数据到数据库_Python--day40(EPOLL的使用、数据库基础)
  6. 该伙伴事务管理器已经禁止了它对远程/网络事务的支持
  7. STL-vector容器
  8. 我的日程安排表(2022-6-6)(内含I、II、III的解法)
  9. Jenkins--下载安装及简单配置
  10. KB和kB,MB和mb,详细解释计算机存储单位
  11. ES6 入门:let
  12. 【分布式】关于分布式“一致性”的讨论
  13. 页面中播放fla文件
  14. 级联(cascade)
  15. 电脑中常用的“扇区”、“簇”、“块”、“页”等概念
  16. 【STM32学习】(19)STM32实现直流电机测转速(霍尔传感器)
  17. SCRM系统助力企业精细化管理会员 再造会员营销
  18. 完整优雅的卸载腾讯云云服务器安全监控组件
  19. 表单验证(验证手机号是否存在,验证码倒计时)
  20. 备战Noip2018模拟赛10(B组) T1 Max 和最大

热门文章

  1. String StringBuilder StringBuffer
  2. 2018牛客网暑假ACM多校训练赛(第六场)I Team Rocket 线段树
  3. SQL数据查询之——单表查询
  4. flash事件冒泡的理解
  5. 人性歪曲的心理调适 一【浮躁心理、偏激心理、自卑心理、自杀心理、愤怒心理】...
  6. .NET+Oracle 9i时产生的未在本地计算机上注册“OraOLEDB.Oracle.1”提供程序
  7. STM32F103/429串口IAP+Ymodem升级
  8. 马斯克、吴恩达等27人出镜:AI可能成为不朽独裁者,人类就像蚂蚁束手就擒
  9. 【附】Python安装
  10. android 扫描SDCard.