问题:

在Java 代码中开了一个线程,死循环定时运行。

右键运行项目,再右键停目项目:

 

发现系统有提示警告:

警告: Web应用程序[ROOT]似乎启动了一个名为[Thread-1]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[
 java.lang.Thread.sleep(Native Method)
 taurus.microservice.Run$1.run(Run.java:46)
 java.lang.Thread.run(Thread.java:745)]
九月 07, 2022 1:36:13 下午 org.apache.coyote.AbstractProtocol stop
信息: 正在停止ProtocolHandler ["http-nio-8090"]
九月 07, 2022 1:36:13 下午 org.apache.coyote.AbstractProtocol destroy
信息: 正在摧毁协议处理器 ["http-nio-8090"]

一开始,我以为线程已经停了,直到我开启了微服务,发现项目都停了,微服务还有不停的注册信息。

经过反复寻找,这才发现:

项目停止后,线程还在跑,而且开几次,就有几个线程在跑,What the fuck。

直到把整个Eclipse 退了,这些线程的运行才消息。

解决:

1、监听项目退出的信息。

package taurus.mvc.http;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import taurus.mvc.tool.Debug;

@WebListener()
public class HttpServletContextListenerForJavax implements ServletContextListener  {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        HttpContext.IsDestroyed=true;
        Debug.log("ServletContext Destroyed!");
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
        
    }
}

退出时,把标识赋到一个全局变量中。

2、在线程里加上判断,如果项目退出,就退出线程的死循环。

 new Thread(new Runnable() {
                    public void run() {
                        Random random=new Random();
                        Debug.log("MicroService.Run.start.Thread.Runnable : Start");
                         while (true)
                            {
                                try
                                {
                                    if(HttpContext.IsDestroyed)
                                    {
                                        Debug.log("MicroService.Run.start.Thread.Runnable : Stoped");
                                        break;
                                    }
                                    AfterRegHost(RegHost());
                                    Thread.sleep(5000+random.nextInt(5000));//5-10秒循环1次。
                                }
                                catch (Exception err)
                                {
                                    Debug.log(err,"Run.start.Thread.Runnable");
                                    try
                                    {
                                        Thread.sleep(5000+random.nextInt(5000));//5-10秒循环1次。
                                    }catch (Exception e)
                                    {}
                                }
                            }
                    }
                }).start();
posted on 2022-09-07 13:46  路过秋天  阅读(3831)  评论(0编辑  收藏  举报
路过秋天