Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent access to static methods which is used to calculate overdue days

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.

like image 836
Yinbin Wang Avatar asked Feb 06 '23 15:02

Yinbin Wang


1 Answers

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:

  • Add 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;

  • Make payDayFormat a ThreadLocal<SimpleDateFormat>, so that each thread has its own copy.
like image 186
Andy Turner Avatar answered Feb 25 '23 05:02

Andy Turner