先来看一个多线程下使用的例子,运行结果会出现异常:import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors; public class SimpleDateFormateTest { public static void main(String[] args) { final DateFormat df = new SimpleDateFormat("yyyyMMdd,HHmmss"); ExecutorService ts = Executors.newFixedThreadPool(100); for (;;) { ts.execute(new Runnable() { @Override public void run() { try { //生成随机数,格式化日期 String format = df.format(new Date(Math.abs(new Random().nextLong()))); System.out.println(format); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } }); } } }SimpledateFormat用于并发环境,正常开放式如下:为了在多线程环境下使用Simpledateformat,有六种方法:Simpledateformat的例子是在需要格式化的地方建立的,SimpleDateFormat实例public用于存储局部变量 static String formatDate(Date date)throws ParseException{ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(date);}这种方法可能会在短时间内创建大量的SimpleDateFormat实例,例如,在excel表格中分析字符串日期。为了避免创建大量的Simpledateformat实例,通常会考虑将Simpledateformat实例设置为静态成员变量,共享Simpledateformat对象。为了避免创建大量的Simpledateformat实例,方法2经常考虑将Simpledateformat实例设置为静态成员变量,共享Simpledateformat对象。在这种情况下,必须添加Simpledateformat同步。private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static String formatDate(Date date)throws ParseException{ synchronized(sdf){ return sdf.format(date); } }这种方法的缺点也很明显,在高并发性环境下,分析会被阻塞。方法三 方法加同步锁synchronized,同时只有一个线程可以执行类中的某个方法。方法三 方法加同步锁synchronized,同时只有一个线程可以执行类中的某个方法。缺点:性能差,每次锁释放后都要等其他线程进入。方案四 使用第三方包。我试过cn.hutool和common-lang3提供的fastdateformat的最终结果实际上并不令人满意,因为这两个包都没有帮助我检查异常时间。例如,2018年7月32日也被认为是正确的时间格式。方法5(推荐)在高并发环境下有更好的体验,Threadlocal可用于限制SimpledateFormat只能在线程中共享,从而避免了多线程造成的线程安全问题。 private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); }};public static String format(Date date) { return threadLocal.get().format(date);}方案六 DatetimeFormater使用Java8提供新的日期时间API,它包括DateTimeFormatter,用于日期时间格式化,它与SimpleDateFormat有什么不同?两者最大的区别在于Java8的DatetimeFormater也是线程安全的,而SimpledateFormat则不是线程安全的。Stringg分析日期 dateStr= "2016年10月25日"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyyy年MM月dd日”; LocalDate date= LocalDate.parse(dateStr, formatter); 日期转换为字符串LocalDatetime now = LocalDateTime.now(); DateTimeFormatter format = DateTimeFormatter.ofPattern(”yyyy年MM月dd日 hh:mm a"); String nowStr = now .format(format);日期格式由DateTimeFormatter的静态方法ofPattern()构建,一些表示日期或时间的类别,如Localdatetime和Localdate,使用parse和format转换日期和字符串。使用新的API,整个转换过程都不需要考虑线程安全。