2014-01-28 75 views
0

我有一個Java類,可以像這樣啓動線程。此線程必須在static {}部分中啓動。當JVM終止時停止線程並將映射保存到磁盤

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 

A nd終結器不起作用(並且不推薦)。我有什麼替代方案?

+0

不知何故,在關閉JVM之前發出信號。 –

+2

無法加載ObjectOutputStream?你是說班?如果這是唯一的問題,請在shutdownhook之前使用它,以便它已經加載。無論如何,shutdownhook是要走的路。 – Kayaman

+0

關閉掛鉤插入線程。這樣可行。但是在這個線程中,當它被中斷時,我必須將地圖保存到磁盤。這是ObjectInputStream不可用的時候。 – JBalaguero

回答

1

拋出異常,因爲ClassLoader在JVM終止期間嘗試加載新類。一個可能的解決方案是在執行期間至少運行一次整個保存鏈,以確保所有類都被加載。

一般來說,對JVM關閉作出反應並不是一個好主意,因爲一旦並非所有功能仍然可用,並且第二,沒有人能保證JVM確實正常關閉。在某些情況下(例如Linux kill命令),JVM可以立即終止,而無需授予執行保存的時間。如果你想確保數據在重新啓動時可用,則需要經常在兩者之間進行保存,如果可能的話 - 如果JVM在寫入期間終止,則會有某種形式的滾動保存文件。