关于线程安全的困惑 - SimpleDateFormat示例

blo*_*824 11 java spring thread-safety

我有一个关于线程安全的问题.据我所知,SimpleDateFormat不是线程安全的.我想知道如果我在弹簧控制器中使用以下方式会有什么影响:

private final static SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd yyyy", Locale.US);
Run Code Online (Sandbox Code Playgroud)

稍后在我的控制器函数中,我使用它如下:

  try {
        changedate = changedate.substring(0, 15);                                                
        calcDate = dateFormat.parse(changedate);
    } catch (ParseException e2) {
        logger.error("Date Parsing Problem", e2); 
    }
Run Code Online (Sandbox Code Playgroud)

然后将calcDate添加到我的模型对象中,并返回ModelAndView.

那么我会用这种方式看到什么样的问题呢?简单地删除static关键字会修复任何问题,因为每个线程都会使用自己的dateFormat实例吗?关于线程安全性的任何关于线程安全性的清晰度都将非常受欢迎.

谢谢

ata*_*lor 22

SimpleDateFormat.parse()使用一个被调用的实例变量calendar来构建字符串中的日期.如果两个线程同时尝试解析,calendar变量将被破坏,你将得到错误的结果.

使变量不是静态不一定有帮助,因为两个线程仍然可以使用相同的控制器.更好的解决方案是每次解析日期时创建一个新的DateFormat对象,或者使用线程本地存储.更好的是,使用具有线程安全解析器的JodaTime.


axt*_*avt 5

那么我会用这种方式看到什么样的问题呢?

开发人员做SimpleDateFormat了一个非常奇怪的决定 - parse()他们在工作期间将部分解析的日期存储在一个字段中SimpleDateFormat.显然,这意味着您无法parse()同时从多个线程调用.

简单地删除static关键字会修复任何问题,因为每个线程都会使用自己的dateFormat实例吗?

卸下static不会帮你,因为春季控制器单默认作用域,因此Spring使用控制器的单个实例来服务所有请求.