“ Java DateFormat不是线程安全的”这将导致什么?

大家都警告Java DateFormat不能保证线程安全,并且我从理论上理解这个概念。

但是我无法想象由此导致的实际问题。说,我在一个类中有一个DateFormat字段,并且在多线程环境中该类的不同方法(格式化日期)中使用了相同的字段。

这会导致:

  • any exception like format exception
  • discrepancy in data
  • any other issue?

另外,请解释原因。

回答:

这是一个其中多个线程使用共享程序的程序SimpleDateFormat

程序:

public static void main(String[] args) throws Exception {

final DateFormat format = new SimpleDateFormat("yyyyMMdd");

Callable<Date> task = new Callable<Date>(){

public Date call() throws Exception {

return format.parse("20101022");

}

};

//pool with 5 threads

ExecutorService exec = Executors.newFixedThreadPool(5);

List<Future<Date>> results = new ArrayList<Future<Date>>();

//perform 10 date conversions

for(int i = 0 ; i < 10 ; i++){

results.add(exec.submit(task));

}

exec.shutdown();

//look at the results

for(Future<Date> result : results){

System.out.println(result.get());

}

}

运行几次,你将看到:

例外情况:

这里有一些例子:

1。

Caused by: java.lang.NumberFormatException: For input string: ""

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

at java.lang.Long.parseLong(Long.java:431)

at java.lang.Long.parseLong(Long.java:468)

at java.text.DigitList.getLong(DigitList.java:177)

at java.text.DecimalFormat.parse(DecimalFormat.java:1298)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)

2。

Caused by: java.lang.NumberFormatException: For input string: ".10201E.102014E4"

at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)

at java.lang.Double.parseDouble(Double.java:510)

at java.text.DigitList.getDouble(DigitList.java:151)

at java.text.DecimalFormat.parse(DecimalFormat.java:1303)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1589)

3。

Caused by: java.lang.NumberFormatException: multiple points

at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1084)

at java.lang.Double.parseDouble(Double.java:510)

at java.text.DigitList.getDouble(DigitList.java:151)

at java.text.DecimalFormat.parse(DecimalFormat.java:1303)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1936)

at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1312)

错误的结果:

Sat Oct 22 00:00:00 BST 2011

Thu Jan 22 00:00:00 GMT 1970

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Thu Oct 22 00:00:00 GMT 1970

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

正确的结果:

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

Fri Oct 22 00:00:00 BST 2010

在多线程环境中安全使用DateFormats的另一种方法是使用 ThreadLocal变量来保存DateFormat 对象,这意味着每个线程将拥有自己的副本,而无需等待其他线程释放它。这是这样的:

public class DateFormatTest {

private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){

@Override

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyyMMdd");

}

};

public Date convert(String source) throws ParseException{

Date d = df.get().parse(source);

return d;

}

}

以上是 “ Java DateFormat不是线程安全的”这将导致什么? 的全部内容, 来源链接: utcz.com/qa/404783.html

回到顶部