javamultithreadingconcurrencythread-safetyjxls

Java - synchronized DateFormat - jxls


I need to use DateFormat object in jxls beans. If in my class I write the following:

private synchronized DateFormat df = new SimpleDateFormat("dd.MM.yyyy");

Will it be thread-safe? In the same class I have a method:

public void doSomething() {
    Map<String,String> beans = new HashMap<String,String>();
    beans.put("df",df);
    XLSTransformer transformer = new XLSTransformer();
    transformer.transformXLS("template.xls", beans, "result.xls");
}

That is called from multiple threads.

If synchronized field doesn't help in this situation, what can I do to provide thread-safe date formatting from jxls without creating new DateFormat object every time?


Solution

  • No you can't add synchronized to fields like that.

    1. You could create one every time you call doSomething:

    e.g.:

    public void doSomething() {
        Map<String,String> beans = new HashMap<String,String>();
        beans.put("df", new SimpleDateFormat("dd.MM.yyyy"));
        XLSTransformer transformer = new XLSTransformer();
        transformer.transformXLS("template.xls", beans, "result.xls");
    }
    

    Since each calling thread will get its own instance of SimpleDateFormat this will be threadsafe (assuming the SimpleDateFormat doesn't live long and get passed to other threads when it is passed on to the xslt transformer).

    1. Create a ThreadLocal to handle multiple threads:

    e.g.:

    private static final ThreadLocal<SimpleDateFormat> df =
        new ThreadLocal<Integer>() {
             @Override protected Integer initialValue() {
                 return new SimpleDateFormat("dd.MM.yyyy");
         }
     };
     public void doSomething() {
        // ...
        beans.put("df", df.get());
        // ...
    }
    
    1. Another option is to change your code to use the jodatime DateTimeFormat instead. The DateTimeFormat class is thread safe.