SimpleDateFormat non-threading security and workarounds

Source: Internet
Author: User
Tags dateformat string format

I. Why is SIMPLEDATEFORMAT not thread-safe?

Java source code is as follows:

/*** Date  Formats is isn't synchronized.* It's recommended to create separate format instances for each thread.* If multiple threads Access a format concurrently, it must be synchronized* Externally.*/public class SimpleDateFormat extends DateFormat {pub Lic Date Parse (String text, parseposition pos) {calendar.clear ();//Clears all the time fields//other logic ... Date parseddate = Calendar.gettime ();}} Abstract class dateformat{//Other logic ... protected Calendar calendar;public Date Parse (String source) throws Parseexcep        tion{parseposition pos = new parseposition (0);        Date result = Parse (source, POS); if (Pos.index = = 0) throw new ParseException ("Unparseable Date: \" "+ Source +" \ "", Pos.errori        NDEX);    return result; }}
If we define SimpleDateFormat as a static member variable, the SDF object is shared between multiple thread, so the calendar object is also shared.

Assuming that thread A and thread B both enter the parse (text, pos) method, thread B executes to calendar.clear () and thread A executes to Calendar.gettime (), then there is a problem.


Two. The problem recurs:

public class Dateformattest {private static SimpleDateFormat SDF = new SimpleDateFormat ("dd-mmm-yyyy", locale.us);  private static String date[] = {"01-jan-1999", "01-jan-2000", "01-jan-2001"};p ublic static void Main (string[] args) {for (int i = 0; i < date.length; i++) {Final int temp = i;new Thread (new Runnable () {@Overridepublic void run () {try {while (true) {String str1 = date[temp]; String str2 = Sdf.format (Sdf.parse (str1)); System.out.println (Thread.CurrentThread (). GetName () + "," + str1 + "," + str2 "), if (!str1.equals (str2)) {throw new Runtimee Xception (Thread.CurrentThread (). GetName () + ", expected" + str1 + "but got" + str2);}}} catch (Exception e) {throw new RuntimeException ("Parse failed", e);}}). Start ();}}}

Create three processes, use the static member variable SimpleDateFormat the parse and format methods, and compare the values after these two methods toss to be equal:

If the following error occurs, the incoming date is dropped, that is, the SimpleDateFormat is not thread safe:

Exception in Thread "Thread-0" Java.lang.RuntimeException:parse failedat Cn.test.dateformattest$1.run ( dateformattest.java:27) at Java.lang.Thread.run (thread.java:662) caused by:java.lang.runtimeexception:thread-0, Expected 01-jan-1999 but got 01-jan-2000at cn.test.dateformattest$1.run (dateformattest.java:22) ... 1 more

Three. Solution:

1. Solution A:

Define SimpleDateFormat as a local variable:

SimpleDateFormat SDF = new SimpleDateFormat ("dd-mmm-yyyy", locale.us); String str1 = "01-jan-2010"; String str2 = Sdf.format (Sdf.parse (str1));
Disadvantage: A SimpleDateFormat object is created each time the method is called, and the method ends with garbage collection.


2. Solution B:

Add a thread Sync Lock: Synchronized (lock)

public class Syncdateformattest {private static SimpleDateFormat SDF = new SimpleDateFormat ("dd-mmm-yyyy", locale.us);  private static String date[] = {"01-jan-1999", "01-jan-2000", "01-jan-2001"};p ublic static void Main (string[] args) {for (int i = 0; i < date.length; i++) {Final int temp = i;new Thread (new Runnable () {@Overridepublic void run () {try {while (true) {synchronized (SDF) {String s TR1 = Date[temp];D ate date = Sdf.parse (STR1); String str2 = Sdf.format (date); System.out.println (Thread.CurrentThread (). GetName () + "," + str1 + "," + str2 "), if (!str1.equals (str2)) {throw new Runtimee Xception (Thread.CurrentThread (). GetName () + ", expected" + str1 + "but got" + str2);}}} catch (Exception e) {throw new RuntimeException ("Parse failed", e);}}). Start ();}}}
Cons: Poor performance, waiting for other threads to enter after the lock is released each time


3. Solution C: (recommended)

Use threadlocal: Each thread will have its own copy of the SimpleDateFormat object.

Write a tool class:

public class Dateutil {private static threadlocal<simpledateformat> local = new Threadlocal<simpledateformat > ();p ublic static Date parse (String str) throws Exception {SimpleDateFormat SDF = Local.get (); if (SDF = = null) {SDF = n EW SimpleDateFormat ("dd-mmm-yyyy", locale.us); Local.set (SDF); return Sdf.parse (str);} public static String format (date date) throws Exception {SimpleDateFormat SDF = Local.get (); if (SDF = = null) {SDF = new Si Mpledateformat ("dd-mmm-yyyy", locale.us); Local.set (SDF); return Sdf.format (date);}}
Test code:

public class Threadlocaldateformattest {private static String date[] = {"01-jan-1999", "01-jan-2000", "01-jan-2001"};p UB Lic static void Main (string[] args) {for (int i = 0; i < date.length; i++) {final int temp = i;new Thread (New Runnable ( {@Overridepublic void Run () {try {while (true) {String str1 = date[temp];D ate date = Dateutil.parse (STR1); String str2 = Dateutil.format (date); System.out.println (str1 + "," + str2), if (!str1.equals (str2)) {throw new RuntimeException (Thread.CurrentThread (). GetName () + ", expected" + str1 + "but got" + str2);}} catch (Exception e) {throw new RuntimeException ("Parse failed", e);}}). Start ();}}}






SimpleDateFormat non-threading security and workarounds

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.