简体   繁体   English

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

[英]Is the following date formatting code thread safe?

I have read in several places that SimpleDateFormat is not thread-safe, but threading is a concept that is still unclear to me, so I wanted to know if the following code is thread safe; 我已经在多个地方阅读过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());
        }
    }

This is a method that resides in a class called "DateUtils.java" and in the Spring Boot application I am working on, I access it using DateUtils.stringToDate... wherever I need to convert a String to a date (or pass up the exception to the controller if the conversion fails). 这是一种驻留在名为“ DateUtils.java”的类中的方法,在我正在使用的Spring Boot应用程序中,我可以使用DateUtils.stringToDate...访问它DateUtils.stringToDate...无论我需要将String转换为日期(或向上传递)如果转换失败,则为控制器的异常)。

Since this method is using a new instance of SimpleDateFormat each time the method is called, I am going with the belief that it is thread-safe, but I am posting this question here to be corrected if I am wrong. 由于此方法在每次调用该方法时都使用SimpleDateFormat的新实例,因此我相信它是线程安全的,但如果有错,我将在此处发布此问题以予以纠正。 The main reason I am not 100% sure is that even though it is a new instance in each method call, the instance of the DateUtils class (which I believe is not even an instance since it was not even initialized to begin with, please correct me if I am wrong here too) is shared during application runtime. 我不确定100%的主要原因是,尽管它是每个方法调用中的一个新实例,但DateUtils类的实例(我认为它甚至不是实例,因为它甚至没有初始化为开始,请更正我,如果我在这里也错了)在应用程序运行时共享。

Thank you. 谢谢。

Short answer is that what you are doing is absolutely thread safe because: 简短的答案是,您所做的绝对是线程安全的,因为:

  • You are not doing any mutation to global state. 您没有对全局状态做任何更改。
  • You are working with all local variables 您正在使用所有局部变量
  • Your method accepts String as input which is immutable 您的方法接受String作为不可变的输入
  • In the end you are returning "mutable" Date object but you are using " defensive copying ". 最后,您将返回“可变” Date对象,但您将使用“ 防御性复制 ”。

Since this method is using a new instance of SimpleDateFormat each time the method is called, I am going with the belief that it is thread-safe, but I am posting this question here to be corrected if I am wrong. 由于此方法在每次调用该方法时都使用SimpleDateFormat的新实例,因此我相信它是线程安全的,但如果有错,我将在此处发布此问题以予以纠正。

Yes, you are right in your understanding, however some more word of wisdom is that even that could lead to concurrency issue if you are returning that object back or if that object, in some way, accessible outside of that method to other threads, because in that case object of SimpleDateFormat could be mutated. 是的,您的理解是正确的,但是更多的智慧是,如果您将该对象返回或该对象以某种方式可以在该方法之外访问其他线程,那么即使那样也可能导致并发问题,因为在这种情况下,可以SimpleDateFormat对象。

The main reason I am not 100% sure is that even though it is a new instance in each method call, the instance of the DateUtils class (which I believe is not even an instance since it was not even initialized to begin with, please correct me if I am wrong here too) is shared during application runtime. 我不确定100%的主要原因是,尽管它是每个方法调用中的一个新实例,但DateUtils类的实例(我认为它甚至不是实例,因为它甚至没有初始化为开始,请更正我,如果我在这里也错了)在应用程序运行时共享。

You method stringToDate is static which basically means that to access this method you do not need any object of DateUtils , this doesn't cause any concurrency/thread safety issues until you: 您的stringToDate方法是静态的,这基本上意味着访问此方法不需要任何DateUtils对象,这不会导致任何并发/线程安全问题,除非您执行以下操作:

  • You are accessing global state and doing any mutation to global state without any synchronization 您正在访问全局状态并在不进行任何同步的情况下对全局状态进行任何更改
  • Your accepts mutable objects as method parameters, and do not use " defensive copying " before working on them 您接受可变对象作为方法参数,并且在处理它们之前不要使用“ 防御性复制
  • In the end you return a "mutable" object without " defensive copying ". 最后,您将返回一个没有“ 防御性复制 ”的“可变”对象。

This method is thread-safe because it implements the thread safety using stack confinement . 此方法是线程安全的,因为它使用堆栈限制实现了线程安全。 None of the variables are shared by more than one thread since in Java every thread gets its own stack. 没有一个以上的线程共享任何变量,因为在Java中,每个线程都有自己的堆栈。 The formal arguments ( String ) being immutable is also necessary for the thread safety of this method. 对于此方法的线程安全性, 不可变的形式参数( String )也是必需的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM