java dateformat 线程安全_关于SimpleDateFormat的线程安全问题和解决方案

首先简单说一下SimpleDateFormat存在线程安全问题的原因。SimpleDateFormat继承了DateFormat类,类中有一个受保护类型的Calendar对象,再看一下SimpleDateFormat的format方法:

private StringBuffer format(Date date, StringBuffer toAppendTo,

FieldDelegate delegate) {

// Convert input date to time field list

calendar.setTime(date);

boolean useDateFormatSymbols = useDateFormatSymbols();

for (int i = 0; i < compiledPattern.length; ) {

int tag = compiledPattern[i] >>> 8;

int count = compiledPattern[i++] & 0xff;

if (count == 255) {

count = compiledPattern[i++] << 16;

count |= compiledPattern[i++];

}

......

}

相信大家看到标红的这行代码时,都会明白为什么format方法是非线程安全的了。多个线程共享SimpleDateFormat实例时,对Calendar对象的更改会相互影响,因此产生了线程安全问题。

OK,解决方案:

1、每当使用时创建一个SimpleDateFormat的实例,但性能会较差(其实以现在jdk的优异表现和软硬件性能的提升,创建SimpleDateFormat实例对性能的影响并不是很明显)。

2、使用ThreadLocal避免多线程共享实例,代码:

public class ConcurrentDateUtil {

private static ThreadLocal DateThreadLocal = new ThreadLocal() {

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyy-MM-dd");

}

};

private static ThreadLocal DateTimeThreadLocal = new ThreadLocal() {

protected DateFormat initialValue() {

return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

}

};

public static Date parseDate(String dateStr) throws ParseException {

return DateThreadLocal.get().parse(dateStr);

}

public static String formatDate(Date date) {

return DateThreadLocal.get().format(date);

}

public static Date parseDateTime(String dateStr) throws ParseException {

return DateTimeThreadLocal.get().parse(dateStr);

}

public static String formatDateTime(Date date) {

return DateTimeThreadLocal.get().format(date);

}

}

3、一些其他的方法,比如使用synchronized或第三方工具类,前者对性能影响较大,后者不在本文讨论范围内,大家有时间可以自行研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值