热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中的main线程是不是最后一个退出的线程

Java中的main线程是不是最后一个退出的线程个人blog原文地址:http:www.gemoji.mewhen_main_thread_end之所以写这篇文章,是因为上次被人问到这么一个

Java中的main线程是不是最后一个退出的线程

个人blog原文地址http://www.gemoji.me/when_main_thread_end/ 

之所以写这篇文章,是因为上次被人问到这么一个问题:“在main函数里启动一个定时器,是不是main函数执行完整个程序就退出了,包括那个定时器”。多说无益,直接写个程序测试一下就知道了。 
Java代码  收藏代码
  1. public class MainThreadTest {  
  2.    
  3.     public static void main(String[] args) {  
  4.         new Timer().schedule(new TimerTask(){  
  5.    
  6.             @Override  
  7.             public void run() {  
  8.                 System.out.println("Timer thread is running...");  
  9.             }  
  10.    
  11.         }, 500500);  
  12.    
  13.         System.out.println("Main thread ends!");  
  14.     }  
  15. }  

然后你就会发现执行结果是这样的: 
引用
Main thread ends! 
Timer thread is running... 
Timer thread is running... 
Timer thread is running... 

这至少说明main函数执行完毕之后,定时器依旧在运行,那么main线程是否退出了呢?我想不少同学可能会和我之前一样脑补这样的逻辑:“timer线程是main线程创建的,main线程会等到自己创建的所有线程都退出后才会退出”,现实当中我们有时真的会被一些自己妄自推断的结论给弄得雨里雾里,最好的做法是在自己产生一个想法之后想办法去证明它或者证否它。回到这个例子,实际上,当前有哪些线程在运行,我们是可以看到的。怎么看?用java自带的工具jstack就能看到,jstack的使用方法就不多说了,请自行搜索。通过jstack我们可以把jvm当前的线程状态dump下来,在dump结果里你会看到很多陌生的线程,这都没关系,你只需要关注下面的两个线程就好。 
引用
"Timer-0" prio=6 tid=0x01b8f800 nid=0x1330 in Object.wait() [0x0c10f000..0x0c10f 
be8] 
java.lang.Thread.State: TIMED_WAITING (on object monitor) 
at java.lang.Object.wait(Native Method) 
- waiting on <0x03bcdd18> (a java.util.TaskQueue) 
at java.util.TimerThread.mainLoop(Timer.java:509) 
- locked <0x03bcdd18> (a java.util.TaskQueue) 
at java.util.TimerThread.run(Timer.java:462) 

"main" prio=6 tid=0x01989400 nid=0x4b8 at breakpoint[0x003bf000..0x003bfe24] 
java.lang.Thread.State: RUNNABLE 
at me.gemoji.www.test.MainThreadTest.main(MainThreadTest.java:18) 

上面的线程状态是我在main函数中加断点后运行看到的结果,你会看到这时候main线程肯定是还存在的,而且可以明确地看到它处于”at breakpoint”的状态。那么要是我让main函数继续执行下去呢?你会发现main线程不见了,而定时器的线程依旧在运行,这就充分证明main线程在main函数执行完之后就退出了,并不是最后一个退出的线程。 

上面是通过实践得出的结论,下面补充一下理论。stackoverflow上有个类似的问题:When does the main thread stop in Java?,把里面的答案总结一下,基本上就这么三句话: 
  1. JVM会在所有的非守护线程(用户线程)执行完毕后退出;
  2. main线程是用户线程;
  3. 仅有main线程一个用户线程执行完毕,不能决定JVM是否退出,也即是说main线程并不一定是最后一个退出的线程。

关于守护线程的相关知识,大家可以自行搜索下,另外,如果你对jstack打印的结果中的其他线程感兴趣,可以参考这篇文章。

推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了在Java中gt、gtgt、gtgtgt和lt之间的区别。通过解释符号的含义和使用例子,帮助读者理解这些符号在二进制表示和移位操作中的作用。同时,文章还提到了负数的补码表示和移位操作的限制。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了使用postman进行接口测试的方法,以测试用户管理模块为例。首先需要下载并安装postman,然后创建基本的请求并填写用户名密码进行登录测试。接下来可以进行用户查询和新增的测试。在新增时,可以进行异常测试,包括用户名超长和输入特殊字符的情况。通过测试发现后台没有对参数长度和特殊字符进行检查和过滤。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 带你把MySQL索引吃透了
    数据库|mysql教程mysql数据库-mysql教程支付宝网页支付源码,ubuntu脑图,tomcat显示默认主页,爬虫听书软件,php可以开发什么软件,天津关键词seo排名优化 ... [详细]
  • 程序员学习数据库安装教程中必会MySQL使用规范手册
    一个平台或系统随着时间的推移和用户量的增多,数据库操作往往会变慢;而在Java应用开发中数据库更是尤为重要,绝大多数情况下数据库的性能决定 ... [详细]
author-avatar
好人cuiyin_550
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有