DateFormat class is a non -threaded safety class. The Javadocs document mentioned that "Date Formats cannot be synchronized. We recommend creating an independent date format for each thread. If multiple threads access a date format at the same time, this needs to add synchronous code blocks to the outside."
The following code shows us how to use DateFormat in a thread environment to convert the string date to the date object. Creating an example to get the date format is more efficient, because the system does not need to obtain local languages and countries many times.
Public Class DateFormatTest {Private Final DateFormat Format = New SimpleDateFormat ("Yyyymmdd"); Public Date CONVERT (String Source) Throws PARSEEXCEPTION {D ATE D = Format.parse (Source); Return D;}}
This code is non -threaded. We can call it through multiple threads. In the following code, I created a thread pool with two threads, and submitted 5 date conversion tasks. After that, the operating results were viewed:
FINAL DATEFORMATTEST T = New DateFormatTest (); CalLABLE <Date> Task = New CalLABLE <Date> () {Public date call () Throws Exception {Return T.Convert ("20100811" ;}}; // Let's try 2 In the case of a thread. = 0; i < 5; I ++) {results.add (exec.submit (task));} exec.shutdown (); // View results for (future <date> results) {System.out.println (Result.get Cure );}
The operation result of the code is not as we wished-sometimes, it outputs the correct date, and sometimes output errors (such as .sat Jul 31 00:00:00 BST 2012), sometimes even throwing NumberForMatexception!
How to use the DateFormat class concurrently
We can have multiple methods to use the DateFormat class when thread security.
1. Synchronous
The easiest way is to lock the DateFormat object before the date conversion. This method allows only one thread to access the DateFormat object at a time, while other threads can only wait.
Public date convert (String Source) Throws PARSEEXCEPTION {synchronized (format) {date d = format.pars (source); Return d;}}}
2. Use ThreadLocal
Another method is to use the ThreadLocal variable to accommodate the DateFormat object, which means that each thread has a copy that belongs to its own, and no need to wait for other threads to release it. This method will be more efficient than using synchronous blocks.
Public Class DateFormatTest {Private Static Final ThreadLocal <DF = New ThreadLocal <DateFormat> () {{@Override Protected DateFormat () () Return New SimpleDateFormat ("Yyyymmdd");}}; Public date convert (String Source) Throws PARSEEEXCEPTION {Date d = df.get (). PARSE (Source); Return d;}}
3. JODA-TIME
JODA-TIME is a great open source JDK date and a calendar API alternative. The DateTimeFormat is safe and unchanged.
Import org.Joda.time.datetime; Import org.Joda.Time.Format.DateTimeFormat; Import org.JODA.Time.Format.DateTimeFormatter; Import Public Class DateFormatTest {Private Final DateTimeFormatter FMT = DateTimeForpatter ("Yyyymmdd"); Public date convert (string source) {datetime d = fmt.parsedatetime (source); return.todate ();}}