守护进程线程Java

守护进程线程Java,java,concurrency,Java,Concurrency,我是并发和线程的新手,在工作中开发应用程序时一直在使用它们。基本上,我的RMI应用程序(服务器端组件)中有许多线程,它们轮询文件中的更改(这些文件每隔几秒钟更新一次) 在dev-box上进行测试时,我一直在从命令行运行服务器,然后在完成后手动关闭服务器,并冲洗和重复一整天 正如所揭示的,我认为当我关闭命令行并继续处理时,我的线程可能不会停止。这导致了一些非常糟糕的副作用——尽管我不能100%确定这是否可能,所以希望有人能证实这可能是真的 如果我将线程设为守护进程,这是否意味着当我关闭命令行时,这

我是并发和线程的新手,在工作中开发应用程序时一直在使用它们。基本上,我的RMI应用程序(服务器端组件)中有许多线程,它们轮询文件中的更改(这些文件每隔几秒钟更新一次)

在dev-box上进行测试时,我一直在从命令行运行服务器,然后在完成后手动关闭服务器,并冲洗和重复一整天

正如所揭示的,我认为当我关闭命令行并继续处理时,我的线程可能不会停止。这导致了一些非常糟糕的副作用——尽管我不能100%确定这是否可能,所以希望有人能证实这可能是真的

如果我将线程设为守护进程,这是否意味着当我关闭命令行时,这些线程将自动停止?我需要一些很好地终止应用程序的方法,但由于服务器最终将由autosys运行,我不确定关闭时让所有线程完成的最佳方法是什么


感谢

下面的代码演示如何使用虚拟运行任务创建线程池,然后启动该任务,当应用程序终止时,将运行一个关闭挂钩,该挂钩将取消所有正在运行的任务并干净地关闭线程池

您不必像我一样使用Callable,您可以使用Runnables和threadPool.execute方法,并简单地终止threadPool,因为threadPool不那么优雅

    final ExecutorService threadPool = Executors.newCachedThreadPool();
    final List<Future<Void>> runningTasks = new ArrayList<>();
    Future<Void> task = threadPool.submit(new Callable<Void>() {

        @Override
        public Void call() throws Exception {
            int count = 0;
            while(true) {
                System.out.println(++count);
                Thread.sleep(1000);
            }
        }
    });
    runningTasks.add(task);

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            for(Future<Void> runningTask : runningTasks) {
                runningTask.cancel(true);
            }
            threadPool.shutdownNow();
        }
    });
final ExecutorService threadPool=Executors.newCachedThreadPool();
最终列表runningTasks=new ArrayList();
Future task=threadPool.submit(new Callable()){
@凌驾
public Void call()引发异常{
整数计数=0;
while(true){
System.out.println(++计数);
睡眠(1000);
}
}
});
runningTasks.add(任务);
Runtime.getRuntime().addShutdownHook(新线程(){
@凌驾
公开募捐{
对于(未来运行任务:运行任务){
runningTask.cancel(true);
}
threadPool.shutdownNow();
}
});

关机挂钩用于独立应用程序。在JavaEE容器中,您可以对Java虚拟机中运行的javax.servlet.ServletContextListener线程执行相同的操作。如果停止JVM,线程将不再运行。您可以将退出JVM视为拔掉计算机上的插头:任何东西都不能再运行了。

RMI运行时创建了无法停止的线程。关闭服务的唯一方法是使用System.exit()


我在单独的线程中执行此操作。在:new ShutThread().start()之后,关闭线程将等待2秒钟,以便为任何延迟消息提供完成旅程的机会,然后发出System.exit()

这个问题有一个稍有不同的倾向,在正文中还有另一个问题——如果不是很接近的话,我会非常感激。我们的主要问题是因为不了解“守护进程”对Java意味着什么,因此链接到重复的问题。至于您的另一个问题(我假设是关于安全关闭应用程序的问题),因为这是一个单独的问题,所以应该单独提问。因此,对于从命令行启动的服务器来说——没有使用java-jar server.jar的参数——一旦运行,我们如何向它传递一条消息,告诉它优雅地退出?这一点很好。我编写服务器软件,因此包含关闭方法是标准做法。如果其他人不允许这个特性,那么也许他们应该这样做。谢谢你的建议,这是否意味着我将不得不使用servlet上下文侦听器而不是shutdownhook?在独立的Java应用程序中,您可以使用关闭挂钩,在Java web应用程序中,您可以使用ContextListener。取决于您正在清理客户端或服务器上的线程。是,需要停止所有线程。