以下日期格式代码线程安全吗?



我在几个地方读到SimpleDateFormat不是线程安全的,但是线程对我来说仍然不清楚一个概念,所以我想知道以下代码是否线程安全;

static public java.util.Date stringToDate(String strDate, String pattern)
throws ParseException {
if (strDate == null || strDate.trim().equals("")) {
return null;
} else {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return new java.util.Date(sdf.parse(strDate).getTime());
}
}

这是一个驻留在名为"DateUtils.java"的类中的方法,在我正在开发的 Spring Boot 应用程序中,我在需要将字符串转换为日期的任何地方使用DateUtils.stringToDate...访问它(或者在转换失败时将异常传递给控制器)。

由于此方法每次调用该方法时都使用SimpleDateFormat的新实例,因此我认为它是线程安全的,但是如果我错了,我将在此处发布此问题以进行更正。我不是 100% 确定的主要原因是,即使它是每个方法调用中的新实例,DateUtils类的实例(我相信它甚至不是一个实例,因为它甚至没有初始化开始,如果我在这里也错了,请纠正我)在应用程序运行时期间共享。

谢谢。

简短的回答是,您正在做的事情是绝对线程安全的,因为:

  • 您没有对全局状态进行任何更改。
  • 您正在使用所有局部变量
  • 您的方法接受String作为不可变的输入
  • 最后,您返回Date对象"可变",但您使用的是"防御性复制"。

由于此方法使用每个 SimpleDateFormat 的新实例 当该方法被调用时,我相信它是 线程安全,但我在这里发布这个问题,如果我 我错了。

是的,你的理解是正确的,但是更多的智慧是,如果你将那个对象返回回来,或者如果该对象以某种方式在该方法之外被其他线程访问,即使这样也可能导致并发问题,因为在这种情况下,SimpleDateFormat的对象可能会被改变。

我不是 100% 确定的主要原因是,即使它是一个新的 每个方法调用中的实例,DateUtils 类的实例 (我相信这甚至不是一个实例,因为它甚至不是 初始化开始,如果我在这里也错了,请纠正我) 在应用程序运行时共享。

你的方法stringToDate是静态的,这基本上意味着要访问这个方法,你不需要任何DateUtils对象,这不会导致任何并发/线程安全问题,直到你:

  • 您正在访问全局状态并在没有任何同步的情况下对全局状态进行任何更改
  • 您接受可变对象作为方法参数,并且在处理它们之前不要使用"防御性复制">
  • 最后,你返回一个没有"防御性复制"的"可变"对象。

此方法是线程安全的,因为它使用堆栈限制实现线程安全。没有一个变量由多个线程共享,因为在 Java 中每个线程都有自己的堆栈。形式参数(String)是不可变的,对于此方法的线程安全也是必要的。

最新更新