将parse()与Java SimpleDataFormat一起使用时的线程安全性
我尽力研究源代码,找出SimpleDataFormat中parse()的线程安全性不高的原因。但我仍然不知道在何处销毁竞争条件SimpleDataFormat使用DateFormat的将parse()与Java SimpleDataFormat一起使用时的线程安全性,java,thread-safety,simpledateformat,Java,Thread Safety,Simpledateformat,我尽力研究源代码,找出SimpleDataFormat中parse()的线程安全性不高的原因。但我仍然不知道在何处销毁竞争条件SimpleDataFormat使用DateFormat的日历字段来存储正在解析的当前日期。该字段周围没有同步,因此并行使用同一SimpleDataFormat对象可能会并行更改日历值,从而导致结果混乱 PS-I仔细阅读了以下源代码: YMMV.如果我正确理解了您的问题,您可以使用threadlocale package aminur.test.formatters;
日历
字段来存储正在解析的当前日期。该字段周围没有同步,因此并行使用同一SimpleDataFormat对象可能会并行更改日历
值,从而导致结果混乱
PS-I仔细阅读了以下源代码:
YMMV.如果我正确理解了您的问题,您可以使用threadlocale
package aminur.test.formatters;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
public class ThreadSafePriceFormatter {
// the price formats
private static final ThreadLocal<DecimalFormat> pointSeparatedFormat = new ThreadLocal<DecimalFormat>() {
@Override
protected DecimalFormat initialValue() {
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator('.');
return (new DecimalFormat("#0.00", symbols));
}
};
private ThreadSafePriceFormatter() {
}
public static String formatPointSeparated(double price) {
return pointSeparatedFormat.get().format(price);
}
public static Number parsePointSeparated(String price)
throws ParseException {
return pointSeparatedFormat.get().parse(price);
}
}
包aminur.test.formatters;
导入java.text.DecimalFormat;
导入java.text.DecimalFormatSymbols;
导入java.text.ParseException;
公共类ThreadSafePriceFormatter{
//价格格式
私有静态最终ThreadLocal pointSeparatedFormat=new ThreadLocal(){
@凌驾
受保护的DecimalFormat initialValue(){
DecimalFormatSymbols符号=新的DecimalFormatSymbols();
符号。设置小数分隔符('.');
返回(新的十进制格式(“0.00”,符号));
}
};
私有ThreadSafePriceFormatter(){
}
公共静态字符串formatPointSeparated(双倍价格){
返回点separatedFormat.get().format(价格);
}
公共静态编号parsePointSeparated(字符串价格)
抛出异常{
返回点separatedFormat.get().parse(价格);
}
}
从此为避免竞争条件,每次创建新的
SimpleDataFormat
,并仅共享格式字符串:
private static final String DATE_FORMAT = "...";
private void foo() {
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
...
}
如果(且仅当)性能出现问题,您可以为每个线程创建一个
SimpleDateFormat
实例。但通常,每次需要使用时都可以创建一个新实例。SimpleDataFormat还在其解析方法中使用compiledPattern
,该方法定义为:
transient private char[] compiledPattern;
要添加到您的答案中—“在解析之前,将清除日历的所有日期时间字段,并且日历的日期时间字段的默认值将用于任何缺少的日期时间信息。”—请检查此链接。日历字段不再是DateFormat的成员。作为掌握并发编程的智力练习,您是否感兴趣?或者在你的约会时间工作中寻找一个实用的解决方案?