项目场景:
项目场景:常见的表单列表查询
问题描述
列表查询时,需要对数据集for循环一次进行逻辑处理,为了提高执行速度,采用开并行流,这时查询发现有时候报错。定位错误在这一行,日期字符串(firstVoltageTime)转换异常
timeDifference = (voltageTime.getTime() - sdf.parse(firstVoltageTime).getTime()) / 1000;
原因分析:
看源码,发现在parse()方法中这一行代码传入了一个属性calendar,是一个Calendar类的实例对象。
parsedDate = calb.establish(calendar).getTime();
点进该方法
//省略
calendar.clear();
//省略
calendar.set();
//省略
可以发现在这里对calendar进行了修改操作,由于Calendar类不是线程安全的,在并行流中调用则会产生线程安全问题,
解决方案:
方法1:
//修改为线程安全的类,DateTimeFormatter
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//对应部分代码修改
timeDifference = (voltageTime.getTime() - LocalDateTime.parse(firstVoltageTime, formatter).toEpochSecond(ZoneOffset.ofHours(8)) * 1000) / 1000;
方法2:
在每次需要时间操作时new一个SimpleDateFormat,这样保证每一次执行都是独自的对象,这样就不会存在线程安全问题了。