gpt4 book ai didi

java - 如果我在工厂类中实现 ThreadLocal 会发生什么

转载 作者:行者123 更新时间:2023-11-30 08:57:37 24 4
gpt4 key购买 nike

我正在尝试用 Java 实现日期和数字的格式化程序。但是java中的一些格式化程序不是线程安全的,例如。 DecimalFormat,SimpleDateFormat!(首先,我不明白为什么它们不像 DateTimeFormat 那样是线程安全的!)所以,经过一番搜索,我发现了 ThreadLocal 变量。

我见过的关于ThreadLocal的所有片段,他们都使用final。当然,拥有一个格式化程序实例确实有意义。但是,假设我们需要一个格式化程序但用于 3 种模式。

FormatFactory.java

public class FormatFactory {
public static ThreadLocal<DecimalFormat> getMoneyFormatter(final String pattern) {
return new ThreadLocal<DecimalFormat>() {
@Override
public DecimalFormat initialValue() {
DecimalFormat decFormat = new DecimalFormat(pattern);
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
if (!pattern.equals(FormatPatterns.MT940_DECIMAL)) {
symbols.setGroupingSeparator('.');
}
decFormat.setMinimumFractionDigits(2);
decFormat.setDecimalFormatSymbols(symbols);
return decFormat;
}
};
}
}

格式.java

public static String money(BigDecimal amount, String pattern) {
return FormatFactory.getMoneyFormatter(pattern).get().format(amount);
}

用法

Format.money(balance, FormatPatterns.MT940_DECIMAL)
Format.money(balance, FormatPatterns.SIGNED_MONEY)
Format.money(balance, FormatPatterns.MONEY)

在这种用法下它仍然是线程安全的吗???

更新:

答案here解决了我的问题。

我的代码片段如下:

private static final ConcurrentMap<String, ThreadLocal<DecimalFormat>> decimialFormatsByPattern = new ConcurrentHashMap<String, ThreadLocal<DecimalFormat>>();

public static DecimalFormat getMoneyFormatter(final String pattern) {
ThreadLocal<DecimalFormat> decimalFormatter = decimialFormatsByPattern.get(pattern);
if (decimalFormatter == null) {
decimalFormatter = new ThreadLocal<DecimalFormat>() {
@Override
public DecimalFormat initialValue() {
DecimalFormat decFormat = new DecimalFormat(pattern);
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator(',');
if (!pattern.equals(FormatPatterns.MT940_DECIMAL)) {
symbols.setGroupingSeparator('.');
}
decFormat.setMinimumFractionDigits(2);
decFormat.setDecimalFormatSymbols(symbols);
return decFormat;
}
};
decimialFormatsByPattern.putIfAbsent(pattern, decimalFormatter);
}

return decimalFormatter.get();
}

用法

public static String money(BigDecimal amount, String pattern) {
return FormatFactory.getMoneyFormatter(pattern).format(amount);
}

最佳答案

现在,每次调用 getMoneyFormatter 时,您都会返回一个新的 ThreadLocal。你应该只初始化它一次。

但是,使用 ThreadLocal 会导致资源泄漏,因此除非您真的知道自己需要它,否则在需要时创建一个新的格式化程序会更简单。

关于java - 如果我在工厂类中实现 ThreadLocal 会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28061684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com