There are three ways to resolve these security issues.
1). Use Sync
1 Packagecom.bijian.study.date;2 3 Importjava.text.ParseException;4 ImportJava.text.SimpleDateFormat;5 Importjava.util.Date;6 7 Public classDateUtil02ImplementsDateutilinterface {8 9 PrivateSimpleDateFormat DateFormat =NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss");Ten One @Override A Public voidFormat (date date) { - System.out.println (Dateformat.format (date)); - } the - @Override - Public voidParse (String str) { - Try { + synchronized(DateFormat) { - System.out.println (Dateformat.parse (str)); + } A}Catch(ParseException e) { at e.printstacktrace (); - } - } -}
Modify Datemaintest.java dateutilinterface dateutil = new DateUtil01 (), dateutilinterface dateutil = new DateUtil02 (), test OK.
However, when a thread calls this method when a thread is many, the other thread that wants to call this method is block, which can also affect performance to some extent.
2). Create a new SimpleDateFormat instance each time you use it
1 Packagecom.bijian.study.date;2 3 Importjava.text.ParseException;4 ImportJava.text.SimpleDateFormat;5 Importjava.util.Date;6 7 Public classDateUtil03ImplementsDateutilinterface {8 9 @OverrideTen Public voidFormat (date date) { One ASimpleDateFormat DateFormat =NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); - System.out.println (Dateformat.format (date)); - } the - @Override - Public voidParse (String str) { - Try { +SimpleDateFormat DateFormat =NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); - System.out.println (Dateformat.parse (str)); +}Catch(ParseException e) { A e.printstacktrace (); at } - } -}
Modify Datemaintest.java dateutilinterface dateutil = new DateUtil02 (), dateutilinterface dateutil = new DateUtil03 (), test OK.
3). Create only one instance per thread with Threadlocal object
The recommended approach is to create only one instance per thread with the Threadlocal object
For each thread SimpleDateFormat there is no state that affects their collaboration, a copy of the SimpleDateFormat variable is created for each thread or is called a copy, the code is as follows:
1 Packagecom.bijian.study.date;2 3 ImportJava.text.DateFormat;4 Importjava.text.ParseException;5 ImportJava.text.SimpleDateFormat;6 Importjava.util.Date;7 8 Public classDateUtil04ImplementsDateutilinterface {9 Ten Private Static FinalString date_format = "Yyyy-mm-dd HH:mm:ss"; One A //the first call to get will return null - Private StaticThreadLocal ThreadLocal =NewThreadLocal () { - protectedObject InitialValue () { the return NULL;//return null directly - } - }; - + //gets a copy of the variable for the thread, if the first get returns NULL if the InitialValue is not overwritten, it is necessary to initialize a SimpleDateFormat and set to Threadlocal - Public StaticDateFormat GetDateFormat () { +DateFormat DF =(DateFormat) threadlocal.get (); A if(DF = =NULL) { atDF =NewSimpleDateFormat (date_format); - Threadlocal.set (DF); - } - returnDF; - } - in @Override - Public voidParse (String textDate) { to + Try { - System.out.println (GetDateFormat (). Parse (textDate)); the}Catch(ParseException e) { * e.printstacktrace (); $ }Panax Notoginseng } - the @Override + Public voidFormat (date date) { A System.out.println (GetDateFormat (). Format (date); the } +}
Create a threadlocal class variable, which is created with an anonymous class that overrides the InitialValue method, and the primary function is to initialize the instance when it is created.
You can also create it in the following way.
1 Packagecom.bijian.study.date;2 3 ImportJava.text.DateFormat;4 Importjava.text.ParseException;5 ImportJava.text.SimpleDateFormat;6 Importjava.util.Date;7 8 Public classDateUtil05ImplementsDateutilinterface {9 Ten Private Static FinalString date_format = "Yyyy-mm-dd HH:mm:ss"; One A@SuppressWarnings ("Rawtypes") - Private StaticThreadLocal ThreadLocal =NewThreadLocal () { - protected synchronizedObject InitialValue () { the return NewSimpleDateFormat (date_format); - } - }; - + PublicDateFormat GetDateFormat () { - return(DateFormat) threadlocal.get (); + } A at @Override - Public voidParse (String textDate) { - - Try { - System.out.println (GetDateFormat (). Parse (textDate)); -}Catch(ParseException e) { in e.printstacktrace (); - } to } + - @Override the Public voidFormat (date date) { * System.out.println (GetDateFormat (). Format (date); $ }Panax Notoginseng}
Modify Datemaintest.java's Dateutilinterface dateutil = new DateUtil03 (); for dateutilinterface dateutil = new DateUtil04 (); or dateutilinterface dateutil = new DateUtil05 (), test OK.
Finally, the Apache Commons-lang package can also be implemented with Dateformatutils or Fastdateformat, and Apache is guaranteed to be thread-safe and more efficient.
Attached: Oracle official Bug Description: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6178997
Transfer from http://bijian1013.iteye.com/blog/1873336
SimpleDateFormat thread unsafe (GO)