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();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值