ThreadLocal 解决 多线程问题

不仅在客户端, 在服务器端也会有类似问题, servlet是多线程的, 调用后台的service层也是多线程的,如果service层中静态的,或是单例的 成员变量有多线程安全问题,就像 SimpleDataFormat 一样就会出现 取得的日期错误。


---------------------------------
在 log-services 项目中 用多线程来从不同ip下载,解析日志会出现异常。

在使用SimpleDataFormat parse 时, 会出现 NumberFormatException: For input string: ""

原因是SimpleDataFormat 是非线程安全的, 而我代码中的CommonService类中将其作为成员变量使用, 看源代码中 SimpleDataFormat 是 DateFormat的子类, DateFormat中定义了一个 Calendar, 在SimpleDataFormat 中有set(...) get(...)方法, 线程不安全。

参考
[url]http://stackoverflow.com/questions/4021151/java-dateformat-is-not-threadsafe-what-does-this-leads-to[/url]

DateFormat exposes a calendar field of type Calendar, and looking at the code of SimpleDateFormat, some methods call calendar.set(...) and others call calendar.get(...). This is clearly not thread-safe.



解决方法
1, 不使用SimpleDataFormat 的成员变量, 改成零时变量
2, 在所有用到SimpleDataFormat 的地方都加上synchronized
3, 使用ThreadLocal

推荐使用使用ThreadLocal

public class DateFormatTest {

private static final ThreadLocal<DateFormat> df
= new ThreadLocal<DateFormat>(){
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};

public Date convert(String source)
throws ParseException{
Date d = df.get().parse(source);
return d;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值