J2SE - 关于SimpleDateFonnat的线程安全问题

一、问题

    负责日期转换和格式化的SimpleDateFonnat类,在多线程的环境中,很容易出现各种问题,比如转换的时间不正确、线程被挂死、抛出NumberFormatException异常等,因为该类并不是线程安全的

java.lang.NumberFormatException: For input string: ""
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:601)
	at java.lang.Long.parseLong(Long.java:631)
	at java.text.DigitList.getLong(DigitList.java:195)
	at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
	at java.text.DateFormat.parse(DateFormat.java:364)
	at DateFormatTest.run(DateFormatTest.java:24)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

二、方案

    1、局部变量
        高并发的情况下会大量的创建和销毁,非常耗费资源

    public String format(Date date){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        return dateFormat.format(date);  
    }
    2、同步方法/块
        每次执行时都会加锁,高并发时对性能产生很大影响

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    
    public static String formatDate(Date date)throws ParseException{  
        synchronized(DATE_FORMAT){  
            return DATE_FORMAT.format(date);  
        }   
    }  
    3、ThreadLocal
        为每个线程创建一个Format对象,线程只使用自己的
    private static ThreadLocal<DateFormat> LOCAL_DATE_FORMAT = new ThreadLocal<DateFormat>() {  
        @Override  
        protected DateFormat initialValue() {  
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        }  
    };  
  
    public static Date parse(String dateStr) throws ParseException {  
        return LOCAL_DATE_FORMAT.get().parse(dateStr);  
    }  
    4、第三方工具
        比如 Joda-Time 类库,或者 Apache的 commons-lang 包中的 DateFormatUtils 与 FastDateFormat 工具类
    5、JDK8关于Date和Time的新API





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值