当JVM终止时,停止线程并将映射保存到磁盘

时间:2014-01-28 12:36:25

标签: java multithreading jvm

我有一个Java类,可以启动这样的线程。必须在static {}部分中启动此主题。

private static final Thread thCleaner = new Thread(new SessionCleaner(mapSession));
static { thCleaner.start(); }

当JVM终止时,我需要停止此线程并将ConcurrentMap的元素保存到磁盘。

  

从用户自己的评论添加代码:

private void writeMap() { 
   ObjectOutputStream oos = null; 
   try { 
       oos = new   ObjectOutputStream(new FileOutputStream(mapFilePath));
       oos.writeObject(this.mapSession); 
   } 
   catch (Exception e) { 
       e.printStackTrace(); 
   } 
   finally { if (oos != null) { try { oos.close(); } catch (Exception e) {} } } 

}

我尝试了shutdownHook,但我无法加载java.io.ObjectOutputStream来编写地图(因为JVM正在终止),因为它会抛出此异常:

28-ene-2014 13:56:00 org.apache.catalina.loader.WebappClassLoader loadClass INFO: Acceso ilegal: esta instancia de aplicación web ya ha sido parada. 
Could not load java.io.ObjectOutputStream. java.lang.IllegalStateException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:15‌​66) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:295) 
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:627) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
at com.vpfw.tests.skiart.SkiArtDispatchInterruption$1.run 

终结器不起作用(不推荐)。我有哪些替代方案?

1 个答案:

答案 0 :(得分:1)

抛出异常,因为ClassLoader在终止JVM期间尝试加载新类。一种可能的解决方案是在执行期间至少运行一次整个保存链,以确保加载所有类。

一般来说,对JVM关闭做出反应并不是一个好主意,因为一旦并非所有功能仍然可用,并且第二个没人能保证JVM实际上正常关闭。在某些情况下(例如Linux kill命令),JVM可以立即终止,而不会给予执行保存的时间。如果要确保重新启动时数据可用,则需要经常在两者之间进行保存,并且 - 如果可能 - 使用某种形式的滚动保存文件,如果JVM在写入期间终止。