SimpleDateFormat线程安全问题 - 高飞网
190 人阅读

SimpleDateFormat线程安全问题

2016-04-07 18:55:57

    以前只把SimpleDateFormat类当前一个简单的工具类使用,并没有注意它存在的线程安全问题,直到最近在近期一个数据迁移项目中才碰到。我的迁移程序会比较迁移前和后的数据是否一致,在做这个事情的时候,由于之前的数据库中存储的日期使用的14位字符串,即20140502112230,而新库中规范要求使用Timestamp类型,这自然要涉及到日期类型与字符串之间的转化。因为日期格式固定,因此我将这个方法封装在了一个工具类中,并将SimpleDateFormat类的变量声明成了一个类变量,如下:

public class Util {
    // 声明了一个静态变量
    static final SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");

    public static Timestamp str2TimeStamp(String datestr) {
        try {
            if (StringUtils.isBlank(datestr) || datestr.length() != 14) {
                return null;
            }
            Date d = yyyyMMddHHmmss.parse(datestr);
            return new Timestamp(d.getTime());
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return null;
        }
    }

    public static String timeStamp2String(Timestamp t) {
        if (t == null) {
            return null;
        }
        return yyyyMMddHHmmss.format(t);
    }
}

    在执行多线程的比较程序过程中,发现日期值老是错误,断点查看,明明字符串是20140502112230,Timestamp却出现了另外的值,才意识到SimpleDateFormat的线程安全问题,赶紧查看javadoc:

Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

    意思是说,该日期格式类不是同步的。所以建议在使用的时候,为每个线程单独创建一个SimpleDateForm实例。如果非要多个线程并发地访问一个实例,那么必须使用额外的同步。

    




还没有评论!
54.163.164.67