3

I need to start a filewatcher service at the server start. The file watcher service starts in an infinite while loop. So I have started a thread to start the watch service in a loop by overriding the servlet init method. Now when I shutdown tomcat, this thread that is running the loop gets killed abrouptly. There is an error in tomcat logs which says that there is a memory leak issue.Is there a way to stop this thread when the server shutsdown

I have tried to override the destroy method and make while loop condition to false. But I noticed that the destroy method is not getting executed when the server shuts down.

public  static void startFileWatcher() throws InterruptedException {
        Runnable r = () -> {
            try {
                while (!exit) {
                    System.out.println("Exit flag: " + exit);
                    if (FileWatcherUtil.isFileChanged()) {

                        System.out.println("file is changed");
                        Thread.sleep(2000);
                        InstantiateSystemProperties.destroy();
                        System.out.println("Initializing new system properties");
                        SystemPropertiesConfigurer.loadNewXml();
                        InitializeLogger.resetLogger();
                        InstantiateSystemProperties.initializeLoggerObject();
                        NotificationQueue.resetQueue();
                        InstantiateSystemProperties.startThreadPool();
                        Thread.sleep(2000);
                    }
                }
            } catch (InterruptedException | IOException e) {
                e.printStackTrace();
                logger.error("Exception in custom init(): ", e);
            }
        };
        Thread t = new Thread(r);
        t.start();
        t.setDaemon(true);

    }
    public static void stopThread(){
        System.out.println("stopping th thread *********************************************************8");
        SystemPropertiesConfigurer.exit =true;
    }

Servlet destroy: @Override public void destroy() { System.out.println(".........destroy method invoked......."); InstantiateSystemProperties.destroy(); SystemPropertiesConfigurer.stopThread(); }

manjosh
  • 263
  • 2
  • 15
  • 3
    “I have tried to override the destroy method and make while loop condition to false.” Was that condition stored in a `volatile` variable? If not, were you using synchronization or a lock to make sure the changed value was seen in other threads? See [this section](https://docs.oracle.com/javase/specs/jls/se11/html/jls-17.html#jls-17.3) of the Java Language Specification. – VGR Aug 22 '19 at 18:59
  • Also you could make your task responsive to interruption, check `Thread.currentThread().isInterrupted()` in your loop. Then invoke `Thread::interrupt` on your thread in `Servlet::destroy` method. – michalk Aug 22 '19 at 19:21
  • VGR above makes a good suggestion. You can also check out the accepted answer to this question: https://stackoverflow.com/questions/106591/what-is-the-volatile-keyword-useful-for Can you show us your code ? Or if you were able to fix your problem answer your own question ? – Patrick Aug 23 '19 at 01:28
  • I have added the code snippet, I have used volatile variable – manjosh Aug 23 '19 at 04:36
  • 1
    You're doing a `new Thread()` in a Java EE / Servlet based environment..?? STOP!! Please drop everything and redo based on https://stackoverflow.com/q/4691132 – BalusC Aug 23 '19 at 16:19
  • Thanks, I will redo my code with your approach. I have another doubt related to the timer, I have to schedule something at an interval of 1 sec, and this interval can change dynamically, how do I achive that. Currently, I am using a timer, it gets stopped if there is an user input and starts with the new values. – manjosh Aug 23 '19 at 17:35

0 Answers0