• Java Servlet 入门: 问题系列:警告: Web应用程序[ROOT]似乎启动了一个名为[Thread1]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪


    问题:

    在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();
  • 相关阅读:
    应届毕业生简历撰写技巧
    【LeetCode】- Longest Substring Without Repeating Characters
    线性规划
    什么是凸规划
    最优化算法 (一)
    香农定理和频谱效率
    虚函数的用法
    QT学习一
    努力!
    Qslider
  • 原文地址:https://www.cnblogs.com/cyq1162/p/16665142.html
Copyright © 2020-2023  润新知