2013-07-03 1 views
0

Je souhaite tester un correctif où SimpleDateFormat a été utilisé en tant que variable de classe statique. Je recevaisTest de plusieurs threads appel pour SimpleDateFormat

Auparavant mon code était

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 

    } 
} 

Pour celui-ci, je devenais ci-dessous exception

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) 

Maintenant, je l'ai changé à changé:

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 
    } 
} 

Comment puis-je tester que le second est un correctif approprié? Existe-t-il un moyen pour JUnits de tester le multithreading?

+0

Voir aussi https://stackoverflow.com/questions/12159/how-should-i-unit- test-threaded-code – Raedwald

Répondre

4

SimpleDateFormat est pas thread-safe, comme indiqué dans le javadoc:

formats de date ne sont pas synchronisés. Il est recommandé de créer des instances de format distinctes pour chaque thread. Si plusieurs threads accèdent simultanément à un format, ils doivent être synchronisés de manière externe.

Mais ici vous même de jouer avec des références en raison de:

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

Depuis DateFormatter était statique, son contenu a été partagé entre les threads.

Créer une nouvelle instance localement (comme vous l'avez fait par la suite) est une bonne façon de procéder. Les instances locales ne sont pas partagées entre les threads et ne gâcheront pas le multithreading. N'oubliez pas de supprimer le private static SimpleDateFormat dateformatter; pour éviter toute confusion.

Vous pouvez également utiliser une variable ThreadLocal si vous voulez créer seulement 1 instance par fil:

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 
} 
Questions connexes