【问题标题】:Is the following date formatting code thread safe?以下日期格式代码线程安全吗?
【发布时间】:2017-04-22 12:11:50
【问题描述】:

我在几个地方读到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 类的实例(我相信它甚至不是一个实例,因为它甚至没有被初始化,如果我在这里也错了,请纠正我)在应用程序运行时共享。

谢谢。

【问题讨论】:

    标签: java multithreading spring-boot


    【解决方案1】:

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

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

    由于此方法每个都使用 SimpleDateFormat 的新实例 调用该方法时,我相信它是 线程安全,但如果我在此处发布此问题以进行更正 我错了。

    是的,您的理解是正确的,但是如果您要返回该对象,或者如果该对象以某种方式可以在该方法之外访问其他人,那么即使这样也可能导致并发问题线程,因为在这种情况下,SimpleDateFormat 的对象可能会发生变异。

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多