1

我想测试一个将 SimpleDateFormat 用作静态类变量的修复。我得到

以前我的代码是

public class Abc{
   private static SimpleDateFormat dateformatter;

   public static String method1(final Calendar calendar) {
      String thePattern = "ddMMM";
      dateformatter = new SimpleDateFormat(thePattern, Locale.US);
      sPars = dateformatter.format(calendar.getTime());
      //Something

   }

   public static String method2(final Calendar calendar) {
      String thePattern = "ddMMyyyy";
      dateformatter = new SimpleDateFormat(thePattern, Locale.US);
      sPars = dateformatter.format(calendar.getTime());
      //Something

   }
}

对于这个,我低于异常

java.lang.ArrayIndexOutOfBoundsException: 965
            at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
            at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2333)
            at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2248)
            at java.util.Calendar.setTimeInMillis(Calendar.java:1140)
            at java.util.Calendar.setTime(Calendar.java:1106)
            at java.text.SimpleDateFormat.format(SimpleDateFormat.java:955)
            at java.text.SimpleDateFormat.format(SimpleDateFormat.java:948)
            at java.text.DateFormat.format(DateFormat.java:336)

现在我已将其更改为:

public class Abc{  
   public static String method1(final Calendar calendar) {
      String thePattern = "ddMMM";
      SimpleDateFormat dateformatter = new SimpleDateFormat(thePattern, Locale.US);
      sPars = dateformatter.format(calendar.getTime());
      //Something
   }

   public static String method2(final Calendar calendar) {
      String thePattern = "ddMMyyyy";
      SimpleDateFormat dateformatter = new SimpleDateFormat(thePattern, Locale.US);
      sPars = dateformatter.format(calendar.getTime());
      //Something
   }
}

如何测试第二个是否正确修复?JUnits 中有什么方法可以测试多线程吗?

4

1 回答 1

5

SimpleDateFormat 不是线程安全的,如javadoc中所述:

日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,它必须在外部同步。

但是在这里,您甚至因为以下原因而弄乱了引用:

dateformatter = new SimpleDateFormat(thePattern, Locale.US);

由于 dateformatter 是静态的,因此它的内容在线程之间共享。

在本地创建一个新实例(就像你之后所做的那样)是一个很好的方法。本地实例不在线程之间共享,也不会与多线程混淆。

只是不要忘记删除private static SimpleDateFormat dateformatter;以避免混淆。

如果您只想为每个线程创建 1 个实例,也可以使用ThreadLocal变量:

private static final ThreadLocal<SimpleDateFormat> dateformatter1 =
    new ThreadLocal<SimpleDateFormat>() {
         @Override protected SimpleDateFormat initialValue() {
             return new SimpleDateFormat("ddMMM");
     }
 };

private static final ThreadLocal<SimpleDateFormat> dateformatter2 =
    new ThreadLocal<SimpleDateFormat>() {
        @Override protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("ddMMyyyy");
    }
};

public static String method1(final Calendar calendar) {
    SimpleDateFormat dateformatter = dateformatter1.get();
    sPars = dateformatter.format(calendar.getTime());
    //Something
}

public static String method2(final Calendar calendar) {
    SimpleDateFormat dateformatter = dateformatter2.get();
    sPars = dateformatter.format(calendar.getTime());
    //Something
}
于 2013-07-03T10:11:13.303 回答