我是并发和线程的新手 - 并且在开发我的应用程序时一直在使用它们。基本上我在我的RMI应用程序(服务器端组件)中有许多线程来轮询文件中的更改(这些文件每隔几秒更新一次)。
在开发盒上进行测试时,我一直在从命令行运行服务器,然后在完成后手动关闭它并在一整天内进行冲洗和重复。
随着它的发生 - 我认为当我关闭命令行并仍然继续处理时,我的线程可能不会停止。这导致了一些非常糟糕的副作用 - 虽然我不能100%确定这是否可能,所以希望有人可以确认这可能是这种情况。
如果我让一个线程成为一个守护进程 - 这是否意味着当我关闭命令行时 - 这些线程会自动停止?我需要一些方法来很好地终止应用程序,但因为服务器最终将由autosys运行我不确定什么是关闭时所有线程完成的最佳方法
由于
答案 0 :(得分:1)
以下代码演示如何使用虚拟运行任务创建线程池,然后启动该任务,当应用程序终止时,将运行一个shutdown钩子,该钩子取消所有正在运行的任务并干净地关闭线程池。
你不必像我一样使用Callable,你可以使用Runnables和threadPool.execute方法,只需终止一个不那么优雅的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();
}
});
关机挂钩适用于独立应用程序。在Java EE容器中,您可以使用javax.servlet.ServletContextListener
执行相同的操作。答案 1 :(得分:1)
线程在Java虚拟机中运行。如果停止JVM,则线程不再运行。您可以看到退出JVM从计算机上拔下插头:没有任何东西可以再运行了。
答案 2 :(得分:0)
RMI Runtime会创建无法停止的线程。关闭服务的唯一方法是使用System.exit()。
我在一个单独的线程中执行此操作。之后:new ShutThread()。start(),关闭线程等待2秒,给任何延迟消息提供完成旅程的机会,然后发出System.exit()。