Abb*_*ese 0 java multithreading simpledateformat
我想测试一个修复,其中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
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个,我得到了以下异常
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)
Run Code Online (Sandbox Code Playgroud)
现在我已将其更改为:
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
}
}
Run Code Online (Sandbox Code Playgroud)
如何测试第二个是否正确?JUnits有什么方法可以测试多线程吗?
SimpleDateFormat不是线程安全的,如javadoc中所述:
日期格式未同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问格式,则必须在外部进行同步.
但是在这里你甚至搞乱了引用因为:
dateformatter = new SimpleDateFormat(thePattern, Locale.US);
Run Code Online (Sandbox Code Playgroud)
由于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
}
Run Code Online (Sandbox Code Playgroud)