繁体   English   中英

将 parse() 与 Java SimpleDateFormat 一起使用时的线程安全性

[英]thread safety when using parse() with Java SimpleDateFormat

我尽力研究源代码,以找出为什么 SimpleDateFormat 中的 parse() 不是线程安全的。 但我仍然不知道在哪里破坏比赛条件

SimpleDateFormat 使用 DateFormat 的calendar字段来存储正在解析的当前日期。 该字段周围没有同步,因此并行使用相同的 SimpleDateFormat 对象可能会并行更改calendar值,从而导致结果出现乱码。

PS——我仔细阅读了这个源代码: http : //grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/text/SimpleDateFormat.java#SimpleDateFormat.parse%28java。 lang.String%2Cjava.text.ParsePosition%29

天啊。

为了避免竞争条件,每次都创建新的SimpleDateFormat ,并且只共享格式字符串:

private static final String DATE_FORMAT = "...";

private void foo() {
    SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
    ...
}

如果(且仅当)性能成为问题,您可以为每个线程创建一个SimpleDateFormat实例。 但是通常每次要使用它时都创建一个新实例是可以接受的。

SimpleDateFormat 还在其 parse 方法中使用了compiledPattern ,该方法定义为:

transient private char[] compiledPattern;

如果我正确理解您的问题,您可以使用 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);  
 }  
}  

从这个链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM