2012-10-12 86 views
1

我有一個Java應用程序。我正在使用日誌formater對象。所有的日誌消息應該有這個對象。例如java多線程和靜態方法

log.debug(new LogFormatter(x,y,z)) 

但我必須創建新的LogFormatter對象,每個我想記錄。如果我用靜態方法爲例

log.debug(LogFormatter.format(x,y,z)) 

比我沒有創建新的對象。但是在一個多線程應用程序中它會正常工作。

如果兩個線程使用diff值調用,那麼日誌記錄會變得混亂。

或者是線程局部去

+0

這取決於格式方法中的代碼。你可以發佈方法實現嗎? – Peter

+0

我認爲日誌會打印出'timestamp,thread-id/name',我認爲你不會遇到'LogFormatter.format(..)' –

回答

1

我會使用

private final LogFormatter logFormatter; // immutable object. 

log.debug(logFormatter.format(x,y,z)) 

作爲格式化器是不可變的,可以共享。

+0

不適用於靜態方法 – Aubin

+0

給出的第一個示例表明該方法不必是靜態的。我建議避免這種事情的靜態方法,如果你可以,你可能想要能夠改變格式化。 –

+0

但是,如果LogFormatter.format(...)方法是無狀態的(它不使用任何LogFormatter實例全局字段)並不足以確保線程安全(無論它是否爲靜態或不是(顯然它會如果是非靜態的,那麼必須是final的,這樣纔不會在擴展LogFormatter的類中創建有狀態的覆蓋))? –

1

這將取決於執行記錄的最佳方式。如果您將使用本機Java類,那麼您應該使用處理日誌插入的方法或代碼部分的關鍵字synchronize來處理鎖定。

IMO我會建議使用一個日誌庫,像Log4J的是線程安全的:

注意,像JBoss和GlassFish一些Java應用服務器使用Log4j來處理記錄工作。

+0

問題'使用同步日誌不適用於高度併發的應用程序:這是一個瓶頸。 – Aubin

+0

@Aubin'synchronized'與編寫日誌條目的代價相比是微不足道的。我建議你不要以這種方式寫這麼多的日誌,以至於不管用。 –

+0

當您將註銷切換至高於所有瓶頸時,具有登錄功能的多線程高度併發應用程序的行爲完全不同。 – Aubin

0

這取決於兩件事情:

  1. 無論LogFormatter.format(x,y,z)方法是線程安全的。
  2. 您的記錄器實現是否線程安全。

如果這兩個條件都成立,那麼您可以在多線程環境中使用您的方案,並且不會出現錯誤。

具體來說,您的記錄器實現應該是線程安全的,因爲它將對基礎輸出機制的訪問進行同步:例如,通過確保一次只打印一個日誌記錄。

0

爲了避免只有在記錄打開時線程之間的同步,我被用來關聯每個線程的一個日誌鏈。 難點在於將幾個文件加入 - 離線 - 瞭解正在發生的事情。 每行日誌都有一個日期和一個線程ID。