1.Date类为可变的,在多线程并发环境中会有线程安全问题。

(1)可以使用锁来处理并发问题。

(2)使用JDK8  Instant 或 LocalDateTime替代。

2.Calendar的子类为可变的,在多线程并发环境中会有线程安全问题。

(1)可以使用锁来处理并发问题。

(2)使用JDK8  LocalDateTime 替代。

3.DateFormat和SimpleDateFormat不是线程安全的原因

(1)DateFormat中calendar是共享变量,其子类SimpleDateFormat中也是共享变量。

DateFormat源码:

  1. public abstract class DateFormat extends Format {
  2. /**
  3. * The {@link Calendar} instance used for calculating the date-time fields
  4. * and the instant of time. This field is used for both formatting and
  5. * parsing.
  6. *
  7. * <p>Subclasses should initialize this field to a {@link Calendar}
  8. * appropriate for the {@link Locale} associated with this
  9. * <code>DateFormat</code>.
  10. * @serial
  11. */
  12. protected Calendar calendar;

(2)SimpleDateFormat format方法源码:

  1. private StringBuffer format(Date date, StringBuffer toAppendTo,
  2. FieldDelegate delegate) {
  3. // Convert input date to time field list
  4. calendar.setTime(date);
  5.  
  6. boolean useDateFormatSymbols = useDateFormatSymbols();
  7.  
  8. for (int i = 0; i < compiledPattern.length; ) {
  9. int tag = compiledPattern[i] >>> 8;
  10. int count = compiledPattern[i++] & 0xff;
  11. if (count == 255) {
  12. count = compiledPattern[i++] << 16;
  13. count |= compiledPattern[i++];
  14. }
  15.  
  16. switch (tag) {
  17. case TAG_QUOTE_ASCII_CHAR:
  18. toAppendTo.append((char)count);
  19. break;
  20.  
  21. case TAG_QUOTE_CHARS:
  22. toAppendTo.append(compiledPattern, i, count);
  23. i += count;
  24. break;
  25.  
  26. default:
  27. subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
  28. break;
  29. }
  30. }
  31. return toAppendTo;
  32. }

  当多个线程同时使用相同的 SimpleDateFormat 对象【如用static修饰的 SimpleDateFormat 】调用format方法时,多个线程会同时调用 calendar.setTime 方法,可能一个线程刚设置好 time 值另外的一个线程马上把设置的 time 值给修改了导致返回的格式化时间可能是错误的。

4.SimpleDateFormat线程安全使用。

(1)使用ThreadLocal处理static方法

  1. public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
  2. @Override
  3. protected DateFormat initialValue() {
  4. return new SimpleDateFormat("yyyy-MM-dd");
  5. }
  6. };
  1. System.out.println(df.get().format(new Date()));
  1. 2019-12-14

(2)使用JDK8  DateTimeFormatter 替代。

参考:https://www.cnblogs.com/wupeixuan/p/11511915.html?utm_source=gold_browser_extension

  《阿里巴巴Java开发手册》

Java日期时间API系列4-----Jdk7及以前的日期时间类的线程安全问题的更多相关文章

  1. Java日期时间API系列42-----一种高效的中文日期格式化和解析方法

    中文日期(2021年09月11日 和 二〇二一年九月十一日 )在生活中经常用到,2021年09月11日很好处理直接使用模板:yyyy年MM月dd日:二〇二一年九月十一日比较不好处理,需要每个数字进行转 ...

  2. Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate

    通过Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的优点,java8具有很多优点,现在网上查到的农历转换工具类都是基于jdk7及以前的类写的,下面使用ja ...

  3. Java日期时间API系列19-----Jdk8中java.time包中的新的日期时间API类,ZonedDateTime与ZoneId和LocalDateTime的关系,ZonedDateTime格式化和时区转换等。

    通过Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类中时间范围示意图:可以很清晰的看出ZonedDateTime相当于LocalDateTime+ZoneI ...

  4. Java日期时间API系列8-----Jdk8中java.time包中的新的日期时间API类的LocalDate源码分析

    目录 0.前言 1.TemporalAccessor源码 2.Temporal源码 3.TemporalAdjuster源码 4.ChronoLocalDate源码 5.LocalDate源码 6.总 ...

  5. Java日期时间API系列12-----Jdk8中java.time包中的新的日期时间API类,日期格式化,常用日期格式大全

    通过Java日期时间API系列10-----Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter, 可以看出java8的DateTimeFormatter完美解决 ...

  6. SQL Server时间粒度系列----第4节季、年时间粒度详解

    本文目录列表: 1.SQL Server季时间粒度2.SQL Server年时间粒度 3.总结语 4.参考清单列表   SQL Serve季时间粒度       季时间粒度也即是季度时间粒度.一年每3 ...

  7. Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类

    因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...

  8. Java日期时间API系列13-----Jdk8中java.time包中的新的日期时间API类,时间类转换,Date转LocalDateTime,LocalDateTime转Date等

    从前面的系列博客中可以看出Jdk8中java.time包中的新的日期时间API类设计的很好,但Date由于使用仍非常广泛,这就涉及到Date转LocalDateTime,LocalDateTime转D ...

  9. Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的特点

    1.不变性 新的日期/时间API中,所有的类都是不可变的,这对多线程环境有好处. 比如:LocalDateTime 2.关注点分离 新的API将人可读的日期时间和机器时间(unix timestamp ...

  10. Java日期时间API系列1-----Jdk7及以前的日期时间类

    先看一个简单的图: 主要的类有: Date类负责时间的表示,在计算机中,时间的表示是一个较大的概念,现有的系统基本都是利用从1970.1.1 00:00:00 到当前时间的毫秒数进行计时,这个时间称为 ...

随机推荐

  1. kubernetes部署高可用redis

    本文redis通过helm搭建,提供redis高可用完整的编排,关于Helm的搭建和使用请查看文章<helm的搭建及使用>,其中前一章介绍了Helm搭建,并提供了Helm搭建Harbor的 ...

  2. CH-0304 IncDec Sequence

    0304 IncDec Sequence 0x00「基本算法」例题 描述 给定一个长度为 n(n≤10^5 ) 的数列 {a_1,a_2,…,a_n},每次可以选择一个区间 [l,r],使下标在这个区 ...

  3. 通过修改VAD属性破除锁页机制

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 技术学习来源:火哥(QQ:471194425) 注释:因为自己的知 ...

  4. Python的6种内建序列之通用操作

    数据结构式通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构.在Python中,最基本的数据结构是序列(sequence).序列中的每 ...

  5. linux远程登入/远程上传文件

    一.远程登入 1.安装 Xshell5 2.查看是否具备连接 在linux 主机上输入 chkconfig --list | grep sshd #sshd 0:关闭 1:关闭 2:启用 3:启用 4 ...

  6. vue jsx与render的区别及基本使用

    vue template语法简单明了,数据操作与视图分离,开发体验友好.但是在某些特定场合中,会限制一些功能的扩展,如动态使用过滤器.解析字符串类型的模板文件等.以上功能的实现可以借助vue的rend ...

  7. webpack + typescript + babel打包*.min.js文件的环境配置

    将多个*.ts文件打包成一个*.min.js文件的开发配置 1.初始化 npm init 新建以下文件目录: 2.安装依赖: "devDependencies": { " ...

  8. Linux加密known_hosts文件中的IP

    如何加密known_hosts中的IP地址 很多挖矿会去自动匹配known_hosts文件中的IP地址,然后尝试免密登录,进一步感染更多的主机,所以对该文件进行加密可以阻止这一点. 修改 /etc/s ...

  9. iOS事件传递和事件响应者链 20170810

    一.事件响应者链 事件传递和事件响应链 区别 事件的传递和响应的区别: 事件的传递是从上到下(父控件到子控件),事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件. 引出 当我们手指触摸屏幕 ...

  10. Data Management Technology(3) -- SQL

    SQL is a very-high-level language, in which the programmer is able to avoid specifying a lot of data ...