SimpleDateFormat线程不安全

283 阅读1分钟

SimpleDateFormat用法

SimpleDateFormat是Java提供的一个格式化和解析日期的工具类,它能够将日期格式化字符串,或者将对应的字符串时间格式化日期,但是SimpleDateFormat是线程不安全的

SimpleDateFormat线程不安全

public class SimpleDateFormatDemo {

    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void main(String[] args) {
        for (int i = 0; i < 1_00_00; i++) {
            new Thread(()->{
                System.out.println(simpleDateFormat.format(new Date()));
                String time = simpleDateFormat.format(new Date());
                try {
                    System.out.println(simpleDateFormat.parse(time));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
    }
}

运行上述例子,会发现,会有错误信息抛出

1683469387278.jpg 说明SimpleDateFormat线程不安全的

保证SimpleDateFormat使用是线程安全

(1)使用ThreadLocal

public class SimpleDateFormat1Demo {

    static ThreadLocal<SimpleDateFormat> threadLocal = ThreadLocal.withInitial(
            () -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
    );

    public static void main(String[] args) {
        for (int i = 0; i < 1_00_00; i++) {
            new Thread(() -> {
                SimpleDateFormat simpleDateFormat = threadLocal.get();
                System.out.println(simpleDateFormat.format(new Date()));
                String time = simpleDateFormat.format(new Date());
                try {
                    System.out.println(simpleDateFormat.parse(time));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
    }
}

(2)不用使用static定义全局变量,使用局部变量定义

public class SimpleDateFormat2Demo {
    

    public static void main(String[] args) {
        for (int i = 0; i < 1_00_00; i++) {
            new Thread(() -> {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                System.out.println(simpleDateFormat.format(new Date()));
                String time = simpleDateFormat.format(new Date());
                try {
                    System.out.println(simpleDateFormat.parse(time));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        }
    }
}

(3)加锁保证线程安全

public class SimpleDateFormat2Demo {

    static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void main(String[] args) {
        for (int i = 0; i < 1_00_00; i++) {
            new Thread(() -> {
                synchronized (SimpleDateFormat2Demo.class) {
                    System.out.println(simpleDateFormat.format(new Date()));
                    String time = simpleDateFormat.format(new Date());
                    try {
                        System.out.println(simpleDateFormat.parse(time));
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
        }
    }
}

等等

总结

本文介绍了SimpleDateFormat的线程不安全,所以在使用过程中,要多注意其线程安全的使用