SimpleDateFormat的并发安全工具类
多线程环境下SimpleDateFormat调用format和parse时共享Calendar变量,会引发线程安全问题。使用锁太影响效率,可以使用ThreadLocal解决线程安全问题。
工具类代码如下:
public class DateFormatFactory { private static final Map<String, ThreadLocal<SimpleDateFormat>> pool = new HashMap(); private static final Object lock = new Object(); public DateFormatFactory() { } /** * @author ztt * @Date:2019/9/14 * @param pattern */ public static SimpleDateFormat getDateFormat(final String pattern) { ThreadLocal<SimpleDateFormat> t1 = (ThreadLocal) pool.get(pattern); if (t1 == null) { synchronized (lock) { t1 = (ThreadLocal) pool.get(pattern); if (t1 == null) { synchronized (lock) { t1 = ThreadLocal.withInitial(() -> new SimpleDateFormat(pattern)); } pool.put(pattern, t1); } } } return (SimpleDateFormat) t1.get(); } public static void clear(){ synchronized (lock){ pool.values().forEach(ThreadLocal::remove); } } }
调用使用如下:
SimpleDateFormat dataFormat = DateFormatFactory.getDateFormat("MMddHHmmss");
String timeStr =dataFormat.format(Calendar.getInstance().getTime());
代码解析:
DateFormatFactory.getDateFormat("MMddHHmmss");
DateFormatFactory调用静态方法getDateFormat获取私有静态类Map类型的t1中key为"MMddHHmmss"的value中的SimpleDateFormat变量。
用双检锁单例模式获取t1,t1 = ThreadLocal.withInitial(() -> new SimpleDateFormat(pattern));这个语句说明t1为SuppliedThreadLocal类型的变量。
SuppliedThreadLocal是ThreadLocal的子类,t1.get()时调用initvalue方法。SuppliedThreadLocal中重写了initvalue方法return supplier.get()。
Supplier是函数式接口。所以直接调用到了new SimpleDateFormat(pattern)。返回SimpleDateFormat的同时在当前线程的ThreadLocalMap中存放一份。

浙公网安备 33010602011771号