First, brief
View Sampledateformat Rain source, narrative has:
Synchronizedfor synchronized externally.
Date Formats non-thread safe
We recommend that you create a separate format instance for each thread.
If multiple threads access a format at the same time, it must be synchronized externally
1. Parse () test
1.1. code example
PackageCom.jd.ofc.trace.bi.util;Importjava.text.ParseException;ImportJava.text.SimpleDateFormat;Importjava.util.Date;ImportJava.util.concurrent.ExecutorService;Importjava.util.concurrent.Executors;/** * @authorLihongxu6 *@since2018/1/12 14:36*/ Public classDateTest2extendsThread {Private StaticSimpleDateFormat SDF =NewSimpleDateFormat ("Yyyy-mm-dd"); PrivateString name; PrivateString Datestr; PublicDateTest2 (string name, String datestr) { This. Name =name; This. Datestr =Datestr; } @Override Public voidRun () {Date Date=NULL; Try{Date=Sdf.parse (DATESTR); } Catch(ParseException e) {e.printstacktrace (); } System.out.println (Name+ ": Date:" +date); } Public Static voidMain (string[] args)throwsinterruptedexception {executorservice executor=Executors.newcachedthreadpool (); Executor.execute (NewDateTest2 ("Test_a", "2000-04-28")); Executor.execute (NewDateTest2 ("Test_b", "2017-04-28")); Executor.execute (NewDateTest2 ("Test_c", "2018-04-28")); Executor.shutdown (); }}
View Code
There are two scenarios:
1> answer is not accurate
2> Code Exception:
Exception in Thread "pool-1-thread-1" Exception in Thread "Pool-1-thread-2"java.lang.NumberFormatException:multiple points at sun.misc.FloatingDecimal.readJavaFormatString ( Floatingdecimal.java:1890) at sun.misc.FloatingDecimal.parseDouble (Floatingdecimal.java:110) at java.lang.Double.parseDouble (Double.java:538) at java.text.DigitList.getDouble (Digitlist.java:169) at Java.text.DecimalFormat.parse (Decimalformat.java:2056) at Java.text.SimpleDateFormat.subParse (Simpledateformat.java:1869) at Java.text.SimpleDateFormat.parse (Simpledateformat.java:1514) at Java.text.DateFormat.parse (Dateformat.java:364) at Com.jd.ofc.trace.bi.util.DateTest2.run (Datetest2.java:25) at Java.util.concurrent.ThreadPoolExecutor.runWorker (Threadpoolexecutor.java:1142) at Java.util.concurrent.threadpoolexecutor$worker.run (Threadpoolexecutor.java:617) at Java.lang.Thread.run (Thread.java:745) Java.lang.NumberFormatException:multiple points at sun.misc.FloatingDecimal.readJavaFormatString ( Floatingdecimal.java:1890) at sun.misc.FloatingDecimal.parseDouble (Floatingdecimal.java:110) at java.lang.Double.parseDouble (Double.java:538) at java.text.DigitList.getDouble (Digitlist.java:169) at Java.text.DecimalFormat.parse (Decimalformat.java:2056) at Java.text.SimpleDateFormat.subParse (Simpledateformat.java:1869) at Java.text.SimpleDateFormat.parse (Simpledateformat.java:1514) at Java.text.DateFormat.parse (Dateformat.java:364) at Com.jd.ofc.trace.bi.util.DateTest2.run (Datetest2.java:25) at Java.util.concurrent.ThreadPoolExecutor.runWorker (Threadpoolexecutor.java:1142) at Java.util.concurrent.threadpoolexecutor$worker.run (Threadpoolexecutor.java:617) at Java.lang.Thread.run (Thread.java:745) Test_C:date:Sat APR00:00:00 CST 2018
2. Format test
Sampledateformat Source Format Implementation
// called from Format after creating a fielddelegate Private stringbuffer Format (date date, StringBuffer toappendto, fielddelegate delegate) { // Convert input date to Time field list calendar.settime (date);
Calendar operations are not thread-safe, the use of format is not secure in concurrent scenarios, and the test process is similar to testing the parse process
Second, the settlement
Since SimpleDateFormat itself is not safe, there are two ways of solving it: optimizing the use of the process or finding alternatives.
2.1. Temporary creation
Do not use static, creating a new instance each time you use it.
Public classDatetest { Public StaticString formatdate (date date)throwsparseexception {simpledateformat sdf=NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); returnSdf.format (date); } Public StaticDate Parse (String strdate)throwsparseexception {simpledateformat sdf=NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"); returnSdf.parse (strdate); }}
View Code
Problems that exist:
The Calendar object is used in SimpleDateFormat because it is quite heavy, and in high concurrency it can be a lot of new SimpleDateFormat and destroying SimpleDateFormat, which is extremely resource-intensive.
2.2, synchronized
Synchronizes SimpleDateFormat objects with synchronized.
Problems that exist:
When high concurrency occurs, blocking is used for the object, and other users wait while the current consumer is in use, although the result is correct, but the concurrency becomes queued, which in fact does not resolve the problem, and also affects performance and efficiency.
2.3, ThreadLocal
Use threadlocal to make each thread create an instance object of the current thread's SimpleDateFormat.
Problems that exist:
When using threadlocal, if the process of performing an atomic task is one task per thread, then such a declaration is indistinguishable from the creation of an instance object before each use; If you are using multithreaded Plus task queues, for example, Tomcat has m processing threads, There are n pending task requests outside, so when n tasks are executed, only m SimpleDateFormat instances are created, and for a single processing thread, the execution of the task is orderly, so there is no concurrency for the current thread.
2.4, Apache's dateformatutils and Fastdateformat
Use Org.apache.commons.lang.time.FastDateFormat and org.apache.commons.lang.time.DateFormatUtils.
Problems that exist:
Apache is guaranteed to be thread-safe and more efficient. However, only the format () method in the two classes of dateformatutils and Fastdateformat, all the format methods only accept input of type Long,date,calendar, convert to time string, there is no parse () method, Can be converted from a time string to a time object.
2.5, Joda-time
Use the Joda-time class library.
Existing problems: No
1. Using MAVEN Package
<!--https://mvnrepository.com/artifact/joda-time/joda-time-<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version >2.9.9</version></dependency>
2. Use
joda-time-Alternative to date/time libraries for Java applications, Joda-time makes time and date values easier to manage, manipulate, and understand. In fact, ease of use is the main design goal of Joda. Other goals include extensibility, a complete set of features, and support for multiple calendar systems. And Joda is fully interoperable with the JDK, so you don't have to replace all Java code, only the part of the code that performs date/time calculations.
1. Create a time-represented random moment-for example, December 21, 2015 0:0
New DateTime (2015, 12, 21, 0, 0, 0, 333); //
2. Format Time Output
New DateTime (0, 0, 0, 333); System.out.println (DateTime.ToString ("Yyyy/mm/dd HH:mm:ss EE"));
3. Parsing Text Format time
DateTimeFormatter format = DateTimeFormat. Forpattern ("Yyyy-mm-dd HH:mm:ss"); = DateTime.Parse ("2015-12-21 23:22:45", format); System.out.println (DateTime.ToString ("Yyyy/mm/dd HH:mm:ss EE"));
4. Add 90 days to a date and output the results
New DateTime (1, 1, 0, 0, 0, 0); System.out.println (datetime.plusdays) toString ("E mm/dd/yyyy HH:mm:ss. SSS ");
Note: The previous value of plus has not changed, and a new DateTime is returned
5. How many days are there in the New Year
Public Days daystonewyear (localdate fromdate) { = fromdate.plusyears (1). Withdayofyear (1); return Days.daysbetween (FromDate, newyear);}
6. Conversion to JDK Date object
New DateTime (); // Convert to Java.util.Date object New Date (Dt.getmillis ());
7. Time Zone
// The default setting is Japan time Datetimezone.setdefault (Datetimezone.forid ("Asia/tokyo")); New DateTime (); System.out.println (dt1.tostring ("Yyyy-mm-dd HH:mm:ss")); // London time New DateTime (Datetimezone.forid ("Europe/london")); System.out.println (dt2.tostring ("Yyyy-mm-dd HH:mm:ss"));
8. Calculate intervals and intervals
DateTime begin =NewDateTime ("2015-02-01"); DateTime End=NewDateTime ("2016-05-01"); //Calculate interval Millisecond numberDuration d =NewDuration (begin, end); LongMillis =D.getmillis (); //Calculate interval DaysPeriod p =NewPeriod (begin, End, Periodtype.days ()); intDays =p.getdays (); //calculates whether a specific date is within the rangeInterval Interval =NewInterval (begin, end); Booleancontained = Interval.contains (NewDateTime ("2015-03-01"));
9. Date Comparison
DateTime D1 =NewDateTime ("2015-10-01"); DateTime D2=NewDateTime ("2016-02-01"); //and system time ratioBooleanB1 =D1.isafternow (); BooleanB2 =D1.isbeforenow (); BooleanB3 =D1.isequalnow (); //and other dates thanBooleanF1 =D1.isafter (D2); BooleanF2 =D1.isbefore (D2); BooleanF3 = D1.isequal (D2);
Information:
Joda-time Introduction (Chinese) https://www.ibm.com/developerworks/cn/java/j-jodatime.html
Joda-time documentation (English) http://joda-time.sourceforge.net/
java-tips -007 simpledateformat secure time formatting