I have a static method with the following signature:
private static volatile SimpleDateFormat payDayFormat = new SimpleDateFormat("yyyyMMdd");
public static int overdueDays(String repayDay){
try {
Date billDate = payDayFormat.parse(repayDay);
Calendar startDate = Calendar.getInstance();
startDate.setTime(billDate);
Calendar endDate = Calendar.getInstance();
long end = endDate.getTimeInMillis();
long start = startDate.getTimeInMillis();
Long days = TimeUnit.MILLISECONDS.toDays(Math.abs(end - start));
return days.intValue();
} catch (ParseException e) {
logger.error("判断是否逾期解析时间出错");
}
return 0;
}
When there are multiple calls made to the above method concurrently whith the same parameter,the result different.
56
56
1279716
56
56
56
5
736387
56
-1226645849
56
Only 56 is the right answer. But when I replaced Calendar with Joda-Time ,it returns the right answer.How should I change this code without use Joda-Time or lock,unlock and get the right answer.
It's because of sharing payDayFormat
, which is a SimpleDateFormat
:
Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.
The reason it works with Jodatime is that its date formatters don't have shared mutable state, because it's sensible.
So, you can either:
synchronized
to the method signature;Add a synchronized
block just around where you use payDayFormat
:
Date billDate;
synchronized (payDayFormat) {
billDate = payDayFormat.parse(repayDay);
}
Create a new instance of SimpleDateFormat
inside the method;
payDayFormat
a ThreadLocal<SimpleDateFormat>
, so that each thread has its own copy.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With