Java 并发访问用于计算过期天数的静态方法
我有一个具有以下签名的静态方法:Java 并发访问用于计算过期天数的静态方法,java,concurrency,calendar,Java,Concurrency,Calendar,我有一个具有以下签名的静态方法: private static volatile SimpleDateFormat payDayFormat = new SimpleDateFormat("yyyyMMdd"); public static int overdueDays(String repayDay){ try { Date billDate = payDayFormat.parse(repayDay); Calendar startDate = Ca
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;
}
当同时使用同一参数对上述方法进行多个调用时,结果会不同
56
56
1279716
56
56
56
5
736387
56
-1226645849
56
正确答案只有56个。
但是,当我将日历替换为Joda Time时,它会返回正确的答案。我应该如何更改此代码而不使用Joda Time或lock,unlock并获得正确答案。这是因为共享
payDayFormat
,这是一个:
日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部对其进行同步
它使用Jodatime的原因是它的日期格式化程序没有共享的可变状态,因为它是合理的
因此,您可以:
- 向方法签名添加
李>synchronized
- 在使用
的位置附近添加一个payDayFormat
块:synchronized
Date billDate; synchronized (payDayFormat) { billDate = payDayFormat.parse(repayDay); }
- 在方法内部创建一个新的
实例SimpleDataFormat
- 将
apayDayFormat
,这样每个线程都有自己的副本ThreadLocal
LocalDate
,这样做会更好。