问题:项目上线后,发现一个报表每次查询的时候数据时多时少,本地调试后发现是在线程中使用了SimpleDateFormt对日期进行线程不安全格式化的操作,SimpleDateFormt是基于对一个Calendar对象进行操作,操作完之后会调用clear()方法清空。当A和B线程同时得到该对象并操作,A线程调用parse()方法操作完成后清空了Calendar的值,此时B线程调用parse()方法,就会抛出Mutiple points异常。
解决方法:
1、在线程中创建SimpleDateFormat对象,使用完之后置空
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(strDate);
format = null;
2、使用SimpleDateFormat作为对象锁
3、使用LocalDateTime或者LocalDate
static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd") // 包含时间 yyyy-MM-dd HH:mm:ss
.toFormatter();
当pattern只含日期时yyyy-MM-dd,使用LocalDate
LocalDate localDate = LocalDate.parse(strDate, DATE_TIME_FORMATTER);
ZoneId zoneId = ZoneId.systemDefault();
Instant instant = localDate.atStartOfDay().atZone(zoneId).toInstant();
Date date = Date.from(instant);
当pattern含日期跟时间时yyyy-MM-dd HH:mm:ss,使用LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(strDate, DATE_TIME_FORMATTER);
ZoneId zoneId = ZoneId.systemDefault();
Instant instant = localDateTime.atZone(zoneId).toInstant();
Date date = Date.from(instant);
使用方法
// LocalDate --> String
String strDate = LocalDate.now().format(DATE_TIME_FORMATTER );
// LocalDateTime --> String
String strDate = LocalDateTime.now().format(DATE_TIME_FORMATTER)
// String --> LocalDate
LocalDate localDate = LocalDate.parse("2019-10-10", DATE_TIME_FORMATTER);
// String --> LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse("2019-10-10 10:10:10", DATE_TIME_FORMATTER);
// LocalDate --> Date
// 参考解决方法3
网友评论