javadatesimpledateformatjava-6thread-local

Defining a Constant for new SimpleDateFormat


I am building a java application. My application is not multithreading and i want to declare constant for the SimpleDateFormat so i can use it at multiple place.

1.

public static final ThreadLocal<SimpleDateFormat> DATE_FORMAT_YYYY_MM_DD = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
public static SimpleDateFormat DATE_FORMAT_YYYY_MM_DD = new SimpleDateFormat("yyyy-MM-dd"));

In Normal java application which approach is better. As i know SimpleDateFormat is not thread safe and i am trying to mark it as static which is not good. Which approach is better will be better in normal java application.


Solution

  • tl;dr

    LocalDate               // All java.time classes are threads-safe, unlike the troublesome legacy date-time classes. 
    .parse( "2023-01-23" )  // Parse text in standard ISO 8601 format by default, without defining any formatting pattern. 
    .toString()             // Generate text in standard ISO 8601 format. 
    

    1. versus 2.

    If you are absolutely sure this object will never ever be accessed across threads, then your two options serve equally well.

    If there is any chance of future use of multiple threads, then you must use the first, with a ThreadLocal.

    The SimpleDateFormat class is not thread-safe. This means using an object of that class to parse or generate text across threads may result in undefined behavior. Undefined behavior is bad.

    So the second approach you showed creates one object to be used across threads. Not good. The first approach creates one object per thread, so it can only be used singularly, never used across threads. That is better.

    There is no downside to making a ThreadLocal. So I would certainly recommend that for objects known to be not thread-safe whenever there is any chance of multithreaded use now or in the future.

    java.time

    But the best approach is to stop using SimpleDateFormat. That class is part of the terrible date-time classes that are now legacy, having been supplanted years ago by the modern java.time classes defined in JSR 310.

    One of the many advantages of java.time is thread-safety across all its classes.

    So you can create a DateTimeFormatter (replacement for SimpleDateFormat) any where you want, and use it across threads if you want. No problem.

    For extreme cases where you make heavy use of a DateTimeFormatter, you may want to create a singleton for reuse rather than re-instantiating repeatedly.

    Furthermore, your desired format is the default format used by LocalDate#parse and LocalDate#toString. So no need for any formatter object at all!

    LocalDate ld = LocalDate.parse( "2023-01-23" ) ;
    String output = ld.toString() ;
    

    If stuck on Java 6 or Java 7, add the ThreeTen-Backport library to your project. This library provides much of the java.time functionality with virtually identical API. But I strongly suggest you consider moving to a LTS version of Java: Java 8, 11, or 17.