我们在Tomcat启动过程(Tomcat源代码阅读系列之三)一文中已经知道Tomcat启动以后,会启动6条线程,他们分别如下:
"ajp-bio-8009-AsyncTimeout" daemon prio=5 tid=7f8738afe000 nid=0x115ad6000 waiting on condition [115ad5000]
"ajp-bio-8009-Acceptor-0" daemon prio=5 tid=7f8738b05800 nid=0x1159d3000 runnable [1159d2000]
"http-bio-8080-AsyncTimeout" daemon prio=5 tid=7f8735acb800 nid=0x1158d0000 waiting on condition [1158cf000]
"http-bio-8080-Acceptor-0" daemon prio=5 tid=7f8735acd000 nid=0x1157cd000 runnable [1157cc000]
"ContainerBackgroundProcessor[StandardEngine[Catalina]]" daemon prio=5 tid=7f8732850800 nid=0x111203000 waiting on condition [111202000]
"main" prio=5 tid=7f8735000800 nid=0x10843e000 runnable [10843c000]
在这里说明一下Tomcat用到的端口可能更容易理解一些。
8005 远程停服务端口
8080 为HTTP端口,
8443 为HTTPS端口
8009 为AJP端口 APACHE能过AJP协议访问TOMCAT的8009端口。
其中5条是Dameon线程,而对于Java程序来说,当所有非Dameon程序都终止的时候,Jvm就会退出,因此要想终止Tomcat就只需要将main这一条非Dameon线程终止了即可,在org.apache.catalina.startup#Catalina的start()中被一个阻塞等待shutdown的await阻塞,所以main方法才没有退出。
Dameon线程又叫后台或者守护线程,它负责在程序运行期提供一种通用服务的线程,比如垃圾收集线程,非Dameon线程和Dameon线程的区别就在于当程序中所有的非Daemon线程都终止的时候,Jvm会杀死余下的Dameon线程,然后退出。
接下来,我们就来一步步的分析如何来让main线程终止,要想终止它,我们还是得从Tomcat的启动中来寻找答案,我们在分析Tomcat容器启动的时候,在Catalina#start中有一段代码,我们没有关注,接下来就来看看这段代码:
<span style="font-size:18px;">public void start() {
// ignore other code
// Register shutdown hook
// 1
if (useShutdownHook) {
if (shutdownHook == null) {
shutdownHook = new CatalinaShutdownHook();
}
Runtime.getRuntime().addShutdownHook(shutdownHook);
// If JULI is being used, disable JULI's shutdo