SimpleDateFormat
类是非线程安全的,因此在多线程环境下并发使用同一个 SimpleDateFormat
对象可能会导致线程安全问题。例如,在多个线程同时使用同一个 SimpleDateFormat
对象对日期进行格式化或解析时,就可能会抛出异常或得到错误的结果。
为了解决该问题,可以使用以下两种方式:
- 使用
ThreadLocal
对象创建多个SimpleDateFormat
实例,确保每个线程都使用自己的SimpleDateFormat
实例。
public class DateUtils {
private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat(DEFAULT_PATTERN);
}
};
public static String formatDate(Date date) {
SimpleDateFormat sdf = threadLocal.get();
return sdf.format(date);
}
public static Date parseDate(String dateString) throws ParseException {
SimpleDateFormat sdf = threadLocal.get();
return sdf.parse(dateString);
}
}
在上述代码中,定义了一个 DateUtils
工具类,使用 ThreadLocal
对象创建多个 SimpleDateFormat
实例,并使用 get()
方法获取当前线程的 SimpleDateFormat
实例,以确保每个线程都使用自己的 SimpleDateFormat
实例进行日期格式化和解析。
- 使用 Java 8 中提供的线程安全的日期时间格式化类
DateTimeFormatter
。
public class DateUtils {
private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);
public static String formatDate(Date date) {
return dateTimeFormatter.format(date.toInstant().atZone(ZoneId.systemDefault()));
}
public static Date parseDate(String dateString) throws ParseException {
LocalDateTime localDateTime = LocalDateTime.parse(dateString, dateTimeFormatter);
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
}
在上述代码中,使用 DateTimeFormatter
类进行日期时间格式化和解析,该类是线程安全的,可以在多线程环境中使用。使用 ofPattern
方法创建 DateTimeFormatter
实例,并使用 format
和 parse
方法进行日期时间格式化和解析。需要注意的是,需要将 Date
类型转换为 LocalDateTime
类型进行解析,然后再将 LocalDateTime
类型转换为 Date
类型。