Links

  • 1. Sogeti
  • 2. JBoss
  • 3. IBM
  • 4. Oracle
  • 5. SpringSource
  • 6. NL-JUG
  • 7. Java

Archives

Syndication  RSS 2.0

RSS 1.0
RSS 2.0

Bookmark this site

Add 'JCN Blog' site to delicious  Add 'JCN Blog' site to technorati  Add 'JCN Blog' site to digg  Add 'JCN Blog' site to dzone

Posted by Martijn van de Rijdt at 11:53 on Monday 3 June    Add 'Hoe simpel is SimpleDateFormat?' site to delicious  Add 'Hoe simpel is SimpleDateFormat?' site to technorati  Add 'Hoe simpel is SimpleDateFormat?' site to digg  Add 'Hoe simpel is SimpleDateFormat?' site to dzone

Het komt nog wel eens voor dat je een datum/tijd wilt parsen. Hiervoor kunnen we in Java de standaard Java-klasse SimpleDateFormat gebruiken, op de volgende manier:

private void mijnMethode() {
   ...
   DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   Date date = dateFormat.parse(text);
   ...
}

Dit is correct, maar heeft wel een nadeel: elke keer dat mijnMethode uitgevoerd wordt, instantieert de JVM een nieuwe SimpleDateFormat en dat is een dure operatie. Het zou dus beter zijn om deze eenmaal aan te maken en vervolgens te hergebruiken.

Het ligt nogal voor de hand dit te doen door de DateFormat als constante op te slaan:

// DateFormat als constante; LET OP: niet threadsafe!
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
 
private void mijnMethode() {
   ...
   Date date = DATE_FORMAT.parse(text);
   ...
}

Dit heb ik in het verleden ook een aantal keer geschreven, en ik kom dit nog regelmatig tegen in projecten waar ik aan werk. Helaas is deze oplossing niet correct! (Zonder extra synchronisatie tenminste.)

In de kleine lettertjes van de Javadoc van SimpleDateFormat staat namelijk:


Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Als mijnMethode in meerdere threads gebruikt wordt kan de parse-methode falen met een exceptie of, erger nog, een foute Date teruggeven.

Gelukkig geeft de Javadoc ook een tip: maak een instantie aan per thread. Een makkelijke manier om dit te doen is met behulp van ThreadLocal. De code komt er dan als volgt uit te zien:

// SimpleDateFormat gewrapt in een ThreadLocal, omdat SimpleDateFormat niet threadsafe is.
private static final ThreadLocal<DateFormat> DATE_FORMAT = new ThreadLocal<>() {
   @Override
   protected DateFormat initialValue() {
       return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   }
};
 
private void mijnMethode() {
   ...
   Date date = DATE_FORMAT.get().parse(text);
   ...
}

© 2020 Java Competence Network. All Rights Reserved.