SimpleDateFormat 为静态对象,都多个线程同时解析调用parse方法时 parse()调用情况:
    1)先调用DateFormat对象的public Date parse(String source) throws ParseException
    2)DateFormat对象的parse方法调用SimpleDateFormat对象的public Date parse(String text, ParsePosition pos)
    3)SimpleDateFormat对象的parse方法调用 CalendarBuilder 对象的 Calendar establish(Calendar cal)
    4)在 establish()中,做了cal.clear();把calendar清空且没有设置新值。如果此时线程A将calendar清空且没有设置新值,线程B也进入parse方法用到了SimpleDateFormat对象中的calendar对象,此时就会产生线程安全问题!

    1. public class SimpleDateFormatDemo {
    2. private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    3. public static Date parse(String strDate) throws ParseException {
    4. return sdf.parse(strDate);
    5. }
    6. public static void main(String[] args) throws InterruptedException {
    7. ExecutorService service = Executors.newFixedThreadPool(100);
    8. for (int i = 0; i < 20; i++) {
    9. service.execute(() -> {
    10. for (int j = 0; j < 10; j++) {
    11. try {
    12. System.out.println(parse("2021-05-02 23:58:36"));
    13. } catch (ParseException e) {
    14. e.printStackTrace();
    15. }
    16. }
    17. });
    18. }
    19. //等待上述的线程执行完
    20. service.shutdown();
    21. service.awaitTermination(1, TimeUnit.DAYS);
    22. }
    23. }