使用Spring和Apache Commons IO的Web应用程序和目录观察器的线程问题

时间:2016-05-22 23:49:48

标签: java spring multithreading apache-commons-io

我正在使用带有Apache Tomcat 8.5的Spring Framework 4.2开发Web应用程序。当我修改目录中的文件时,我需要调用bean对象中的方法来重新加载信息。 我使用Apache Commons IO来查看目录,但是当我取消部署应用程序时,扫描目录的线程仍然存在。

这是观看更改的代码

    final File directory = new File(groupsDirectory);
    FileAlterationObserver fao = new FileAlterationObserver(directory);
    fao.addListener(new FileAlterationListenerImpl());
    final FileAlterationMonitor monitor = new FileAlterationMonitor(pollingInterval);
    monitor.addObserver(fao);
    monitor.start();

这是我取消部署web应用程序时Tomcat向我显示的消息:

  

22-May-2016 19:13:14.377警告[http-nio-8084-exec-12] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[Argo]似乎已经启动了一个名为[ Thread-12]但未能阻止它。这很可能造成内存泄漏。堆栈跟踪线程:    java.lang.Thread.sleep(Native方法)    org.apache.commons.io.monitor.FileAlterationMonitor.run(FileAlterationMonitor.java:188)    java.lang.Thread.run(Thread.java:745)

3 个答案:

答案 0 :(得分:0)

你可以做的是实现一个ServletContextListener,如本文所述:Call method on undeploy from a Java web-application

然后,您应该可以使用contextDestroyed()的{​​{1}}方法停止监视器。

我建议让一个Factory对象保留在 static 监视器实例上,然后你可以调用Factory,而不是让ServletContextListener直接处理监视器。

工厂将坚持使用类加载器的生命周期(例如,启动webapp的持续时间)

答案 1 :(得分:0)

我只是使用注释@PreDestroy在应用程序停止之前停止监视器。

@Component
public class GroupsMonitor {

    private final FileAlterationMonitor monitor;

    @Autowired
    public GroupsMonitor(@Value("${groups.directory}") String groupsDirectory,
            @Value("${groups.intervalMonitor}") long pollingInterval) throws Exception {
        final File directory = new File(groupsDirectory);
        FileAlterationObserver fao = new FileAlterationObserver(directory);
        fao.addListener(new FileAlterationListenerImpl());
        monitor = new FileAlterationMonitor(pollingInterval);
        monitor.addObserver(fao);
        monitor.start();
    }

    @PreDestroy
    public void stop() {
        try {
            monitor.stop();
        } catch (Exception ex) {
            Logger.getLogger(StopWatcher.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

答案 2 :(得分:0)

旧回答但FileAlterationMonitor仍然存在问题。

即使您致电FileAlterationMonitor#stop(),显示器也不会停止,直到pollingInterval延迟结束。

请参阅:https://github.com/apache/commons-io/pull/58

解决问题的另一种方法是为pollingInterval设置一个小值。