Thread-unsafe use of DateFormat¶
ID: java/thread-unsafe-dateformatKind: problemSecurity severity: Severity: warningPrecision: mediumTags: - quality - reliability - correctness - concurrencyQuery suites: - java-security-and-quality.qls
Click to see the query in the CodeQL repository
Static fields of typejava.text.DateFormat or its descendants should be avoided because the classDateFormat is not thread-safe.
Recommendation¶
Use instance fields instead and synchronize access where necessary.
Example¶
In the following example,DateFormattingThread declares a static fielddateF of typeDateFormat. When instances ofDateFormattingThread are created and run byDateFormatThreadUnsafe, erroneous results are output becausedateF is shared by all instances ofDateFormattingThread.
classDateFormattingThreadimplementsRunnable{publicstaticDateFormatdateF=newSimpleDateFormat("yyyyMMdd");// Static field declaredpublicvoidrun(){for(inti=0;i<10;i++){try{Dated=dateF.parse("20121221");System.out.println(d);}catch(ParseExceptione){}}}}publicclassDateFormatThreadUnsafe{publicstaticvoidmain(String[]args){for(inti=0;i<100;i++){newThread(newDateFormattingThread()).start();}}}
In the following modification of the above example,DateFormattingThread declares aninstance fielddateF of typeDateFormat. When instances ofDateFormattingThread are created and run byDateFormatThreadUnsafeFix, correct results are output because there is a separate instance ofdateF for each instance ofDateFormattingThread.
classDateFormattingThreadimplementsRunnable{privateDateFormatdateF=newSimpleDateFormat("yyyyMMdd");// Instance field declaredpublicvoidrun(){for(inti=0;i<10;i++){try{Dated=dateF.parse("20121221");System.out.println(d);}catch(ParseExceptione){}}}}publicclassDateFormatThreadUnsafeFix{publicstaticvoidmain(String[]args){for(inti=0;i<100;i++){newThread(newDateFormattingThread()).start();}}}
References¶
Java API Specification:java.text.DateFormat synchronization.