SimpleDateFormat多线程问题及解决方案

问题描述:

多线程下,使用SimpleDateFormat会有如下异常报错信息:(多次执行以下代码,可以得到以下3种结果。)

  • case1: java.lang.NumberFormatException: multiple points
  • case2: 错误的结果
  • case3: java.lang.NumberFormatException: For input string: “”
    代码如下:
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
* 10个线程同时调用一个SimpleDateFormat实例格式化日期字符串
*/
public class SimpleDateFormatTest {

   private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

   Date format(String str) {
       Date s = null;
       try {
           s = sdf.parse(str);
           System.out.println(Thread.currentThread().getName() + ":" + s.toString());
       } catch (ParseException e) {
           e.printStackTrace();
       }
       return s;
   }

   @Test
   public void test1() {
       for (int i = 0; i < 10; i++) {
           new Thread(() -> {
               format("20200816");
           },"Thread"+i).start();
       }
   }
}

解决方案:

  1. 每次都实例化一个SimpleDateFormat,当调用format()的时候。
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
  1. 使用ThreadLocal
import org.junit.Test;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 10个线程同时调用一个SimpleDateFormat实例格式化日期字符串
 */
public class SimpleDateFormatTest {

    private static final String DATE_FORMATTER = "yyyyMMdd";
    private static ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<>();

    private SimpleDateFormat getDateFormat() {
        SimpleDateFormat format = sdf.get();
        if (null == format) {
            format = new SimpleDateFormat(DATE_FORMATTER);
            sdf.set(format);
        }
        return format;
    }

    Date format(String str) {
        Date s = null;
        try {
            s = getDateFormat().parse(str);
            System.out.println(Thread.currentThread().getName() + ":" + s.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return s;
    }

    @Test
    public void test1() {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                format("2020-08-16");
            },"Thread"+i).start();
        }
    }
}


版权声明:本文为chenwen0326原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。