以下日期格式化代码线程是否安全?

时间:2017-04-22 12:11:51

标签: java multithreading spring-boot

我在几个地方读过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...访问它,无论我需要将String转换为日期(或者如果转换失败,则将异常传递给控制器​​。)

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

谢谢。

2 个答案:

答案 0 :(得分:2)

简短的回答是你所做的绝对是线程安全的,因为:

  • 你没有对全球状态做任何突变。
  • 您正在使用所有本地变量
  • 您的方法接受String作为输入,这是不可变的
  • 最后,您将返回“可变”Date个对象,但您使用的是“defensive copying”。
  

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

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

  

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

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

  • 您正在访问全局状态并在没有任何同步的情况下对全局状态执行任何突变
  • 您接受可变对象作为方法参数,并且在处理它们之前不要使用“defensive copying
  • 最后,您返回一个没有“defensive copying”的“可变”对象。

答案 1 :(得分:1)

此方法是线程安全的,因为它使用堆栈限制实现线程安全。这些变量都不是由多个线程共享的,因为在Java中,每个线程都有自己的堆栈。正式参数(String immutable 对于此方法的线程安全性也是必需的。