2017-04-22 58 views
0

我已经在几个地方看过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”级,并在春季启动应用程序我工作的方法,我访问使用DateUtils.stringToDate...它无论我需要一个字符串转换为一个日期(或如果转换失败,则将异常传递给控制器​​)​​。

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

谢谢。

回答

2

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

  • 你没有做任何突变的全局状态。
  • 您与所有局部变量
  • 你的方法接受String作为输入,这是不可改变的
  • 在您返回“可变” Date对象,但使用的是“defensive copying”结束工作。

由于这种方法是使用的SimpleDateFormat的一个新实例 时间的方法被调用时,我的信念,这是 线程安全的打算,但我在这里张贴了这个问题如果我 是错的,那么要纠正。

是的,你是对你的理解,但是一些智慧的多个单词的是,甚至有可能导致并发性问题,如果你是返回该对象后面,或者如果该对象,在某种程度上,那外部访问方法到其他线程,因为在这种情况下,SimpleDateFormat的对象可能会发生变化。

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

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

  • 你是访问全局状态和做任何突变全局状态没有任何同步
  • 你接受可变对象作为方法参数,并且对他们的工作
  • 在你retur结束前不要使用“defensive copying” n没有“defensive copying”的“可变”对象。
1

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