2012-01-03 63 views
1
登錄任何類

假設一個shutdownHook爲:如何允許從shutdownHook

class ShutdownHolder extends Thread { 

    public void run() { 
     Logger logger = LoggerFactory.getCoreLogger(ShutdownHolder.class); 
     try { 
     logger.info("Shutdown hook is running..."); 
     doSomething(); 
     logger.info("Shutdown hook end."); 
     } catch(Exception e) { 
     logger.severe("Unexpected ERROR during shutdown", e); 
     } 
    } 
    } 

如何避免記錄ShutdownHook結束之前不會被關閉?

例如,doSomething()方法可以在其他可訪問的類上調用幾個方法,也可以寫入日誌。我不想跳過所有這些日誌。

+0

你是什麼意思?爲什麼記錄儀會關閉? 'doSomething()'應該返回到'run()'方法,不是嗎? – adarshr 2012-01-03 16:26:27

+0

http://docs.oracle.com/cd/E17409_01/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29「他們也不應該盲目地依賴服務可能已經註冊了自己的關機掛鉤,因此可能自己正在關機。「記錄器似乎有它自己的shutdownHook。 – Mik378 2012-01-03 16:33:41

回答

1

所以,除了一些反省黑客之外,我不覺得一個簡單的方法來做到這一點不幸。在1.6 JDK下,關機掛鉤存儲在IdentityHashmap中,該訂單不提供有保證的訂單。實際上,關閉掛鉤是以隨機順序調用的,這取決於該地圖的內部。

在反思方面,我試着做下面的事情,但hookMap對我來說是空的。如果你能得到它的工作,那麼你可能會刪除log4j鉤子,並在鉤子或其他東西結束時手動調用它。

Class<?> clazz = Class.forName("java.lang.ApplicationShutdownHooks"); 
Field field = clazz.getDeclaredField("hooks"); 
field.setAccessible(true); 
@SuppressWarnings("unchecked") 
Map<Thread, Thread> hookMap = (Map<Thread, Thread>) field.get(null); 

然而,我會強烈建議做一些其他比關閉掛鉤。如何在main完成之前調用自己的掛鉤?對我們來說,我們大量使用Spring和DisposableBean模式。那些豆從實例化類的時候開始按相反順序調用,所以依賴於記錄器的任何事物在關閉時仍然具有記錄器。

希望這會有所幫助。