为了账号安全,请及时绑定邮箱和手机立即绑定

Java SImpleDateFormat线程安全问题

Java SImpleDateFormat线程安全问题

智慧大石 2019-03-12 11:10:05
public class Test {    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    private static class Task implements Runnable {        public void run() {            try {                System.out.println(sdf.parse("2016-03-21 12:00:00").getTime());            } catch (ParseException e) {                e.printStackTrace();            }        }    }    public static void main(String[] args) {        Task task = new Task();        Thread t1 = new Thread(task);        t1.start();        Thread t2 = new Thread(task);        t2.start();        Thread t3 = new Thread(task);        t3.start();        Thread t4 = new Thread(task);        t4.start();        Thread t5 = new Thread(task);        t5.start();    }}最近才知道,如果像上面代码那样通过定义静态共享的实例来使用SimpleDateFormat是会存在线程安全问题的。例如线程被挂死:或者转换的时间不对:然后自己尝试读JDK源码来试图分析在SimpleDateFormat的代码中,究竟是哪里的函数或者代码会引起线程不安全,但是由于水平有限,最后还是找不出。哪位大牛可以帮忙分析一下。PS:我的jdk版本:1.8.0_73
查看完整描述

3 回答

?
HUWWW

TA贡献1874条经验 获得超12个赞

我看了一下parse()源代码的注释,有一段是这位的


This parsing operation uses the {@link DateFormat#calendar

  • calendar} to produce a {@code Date}. All of the {@code

  • calendar}'s date-time fields are {@linkplain Calendar#clear()

  • cleared} before parsing, and the {@code calendar}'s default

  • values of the date-time fields are used for any missing

  • date-time information.

大概意思就是parse()方法使用calendar来生成返回的Date实例,问题是这里它用到的calendar不是每次方法执行时都新生成一个,它是定义了一个"protected Calendar calendar"属性,按注释的意思,每次parse之前,都会把calendar里的相关属性都清除,然后用新的处理结果填充此对象,这样的话在多线程里边,parse()执行过程中,就会出现一个线程刚把calendar设置好之后,另一个线程把它给清空了,因为都是一个sdf实例,其他问题原因应该都是这个


查看完整回答
反对 回复 2019-04-17
?
慕的地10843

TA贡献1785条经验 获得超8个赞

private StringBuffer format(Date date, StringBuffer toAppendTo,

                                FieldDelegate delegate) {

        // Convert input date to time field list

        calendar.setTime(date);


        boolean useDateFormatSymbols = useDateFormatSymbols();

        

        ...

 }  


这里使用的calendar是类成员,多线程去setTime会有线程安全问题


查看完整回答
反对 回复 2019-04-17
?
当年话下

TA贡献1890条经验 获得超9个赞

这跟SimpleDateFormat的实现无关,与你多线程使用同一个对象有关,没有做好线程同步


查看完整回答
反对 回复 2019-04-17
  • 3 回答
  • 0 关注
  • 654 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信