在網絡中找不到合適的解決方案,因此我想問問使用java格式的方式是否正確。NumberFormat/DecimalFormat的線程安全動態模式
1)在NumberFormat.java文檔它說,
數字格式通常不同步。建議爲每個線程創建單獨的格式實例。
我們一直在多線程環境中使用格式化對象(靜態初始化),目前沒有問題。這可能是因爲一旦格式被定義,我們的狀態就不會改變(即之後沒有調用者)
2)現在我需要定義一個新格式,它應該在逗號後輸出一個或兩個有效數字,這取決於一些額外的邏輯。我這樣做的方式是定義一個新的格式包裝和委託給兩個不同的DecimalFormat取決於在重寫的#format(double,StringBuffer,FieldPosition)方法中的情況。以下是該代碼:
private final NumberFormat FORMAT = new DecimalFormat() {
private final NumberFormat DECIMAL_FORMAT = new DecimalFormat("0.##");
private final NumberFormat DECIMAL_FORMAT_DIGIT = new DecimalFormat(
"0.0#");
public StringBuffer format(double number, StringBuffer result, java.text.FieldPosition fieldPosition) {
if ((number >= 10 && Math.ceil(number) == number)) {
return DECIMAL_FORMAT.format(number, result, fieldPosition);
} else {
return DECIMAL_FORMAT_DIGIT.format(number, result, fieldPosition);
}
}
};
這是最佳實踐嗎?我擔心沒有實際使用包裝類(它僅用於遵從NumberFormat接口並委託內部格式的所有工作)。我不想調用DecimalFormat#applyPattern(),因爲我認爲這會破壞易失性併發性。
感謝
跨多個線程使用/共享NumberFormat實例是不好的做法。即使您現在沒有遇到任何問題,但是一旦您的應用程序實現了併發處理,它們就會發生。對於使用靜態創建的日期格式的DateFormat,我們有類似的用例,但是我們將應用程序的規模擴大到大量數據處理,其中n個併發進程正在生成數據,我們發現這種格式會給您帶來非常奇怪和意想不到的結果。他們可能不會失敗,但會給出一些意想不到的價值 –
@SangramJadhav,所以你可能保留一個可重用的線程池格式,對吧? – d56
如果你想分享格式,你需要提供我們自己的同步。或者你可以使用ThreadLocal來聲明格式化實例,這樣每個線程都有自己的格式化副本,而且你不必提供同步。 –