SimpleDateFormat的线程安全问题
source link: http://www.lzhpo.com/article/166
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
SimpleDateFormat的线程安全问题
// 如果没有加锁,没有去保证线程安全的话,那这个就是错误的写法,是线程不安全的private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
错误示例:
package com.lzhpo.common.config;import org.junit.jupiter.api.Test;import java.text.ParseException;import java.text.SimpleDateFormat;/** * @author Zhaopo Liu */class DateFormatConfigTest { private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); /** * SimpleDateFormat线程不安全,没有保证线程安全的情况下,禁止使用全局SimpleDateFormat * <pre> * private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); * </pre> */ @Test void testParse() { for (int i = 0; i < 20; ++i) { Thread thread = new Thread(() -> { try { // 错误 System.out.println(SIMPLE_DATE_FORMAT.parse("2020-06-01 11:35:00")); // 正确// System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-06-01 11:35:00")); } catch (ParseException e) { e.printStackTrace(); } }); thread.start(); } }}
从代码中可以看到:SimpleDateFormat继承DateFormat类,在SimpleDateFormat转换日期是通过Calendar对象来操作的,DateFormat类中维护一个Calendar对象,Calendar对象会被用来进行日期-时间计算,既被用于format方法也被用于parse方法。
那就追一下calendar
对象:
来到了CalendarBuilder
的establish
方法:
看一下clear
方法,可以发现它并不是线程安全的,如果此时,a线程将calendar
清空了,calendar
就没有新值了,恰好此时b线程刚好进入到parse
方法用到了calendar
对象,那就会产生线程安全问题了!
不使用静态变量
SimpleDateFormat
,使用局部变量SimpleDateFormat
,每次都new一个。synchronized
等等...保证线程安全的情况下使用静态变量SimpleDateFormat
。使用
ThreadLocal.withInitial
/** * 创建线程局部变量SimpleDateFormat */ private static final ThreadLocal<DateFormat> SAFE_FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));@Testvoid testSafe() { for (int i = 0; i < 20; ++i) { Thread thread = new Thread(() -> { try { System.out.println(SAFE_FORMAT.get().parse("2020-06-01 11:35:00")); } catch (ParseException e) { e.printStackTrace(); } }); thread.start(); }}
- 本文作者: lzhpo
- 本文链接: http://www.lzhpo.com/article/166
- 版权声明: 本文为本人原创文章,采用 CC BY 3.0 CN协议 ,可自由转载、引用,但需署名作者且注明文章出处。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK