zoukankan      html  css  js  c++  java
  • Java日期时间API系列4-----Jdk7及以前的日期时间类的线程安全问题【转】

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

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

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

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

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

    (2)使用JDK8  LocalDateTime 替代。

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

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

    DateFormat源码:

    复制代码

    public abstract class DateFormat extends Format {

    /**
    * The {@link Calendar} instance used for calculating the date-time fields
    * and the instant of time. This field is used for both formatting and
    * parsing.
    *
    * <p>Subclasses should initialize this field to a {@link Calendar}
    * appropriate for the {@link Locale} associated with this
    * <code>DateFormat</code>.
    * @serial
    */
    protected Calendar calendar;

    复制代码

    (2)SimpleDateFormat format方法源码:

    复制代码
        private StringBuffer format(Date date, StringBuffer toAppendTo,
                                    FieldDelegate delegate) {
            // Convert input date to time field list
            calendar.setTime(date);
    
            boolean useDateFormatSymbols = useDateFormatSymbols();
    
            for (int i = 0; i < compiledPattern.length; ) {
                int tag = compiledPattern[i] >>> 8;
                int count = compiledPattern[i++] & 0xff;
                if (count == 255) {
                    count = compiledPattern[i++] << 16;
                    count |= compiledPattern[i++];
                }
    
                switch (tag) {
                case TAG_QUOTE_ASCII_CHAR:
                    toAppendTo.append((char)count);
                    break;
    
                case TAG_QUOTE_CHARS:
                    toAppendTo.append(compiledPattern, i, count);
                    i += count;
                    break;
    
                default:
                    subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
                    break;
                }
            }
            return toAppendTo;
        }
    复制代码

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

    4.SimpleDateFormat线程安全使用。

    (1)使用ThreadLocal处理static方法

    复制代码
        public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
            @Override
            protected DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd");
            }
        };
    复制代码
    System.out.println(df.get().format(new Date()));
    2019-12-14

    (2)使用JDK8  DateTimeFormatter 替代。

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

      《阿里巴巴Java开发手册》

    寻找撬动地球的支点(解决问题的方案),杠杆(Java等编程语言)已经有了。xkzhangsan
     
  • 相关阅读:
    SpringIoC和DI注解开发
    SpringIoC&DI
    Linux基础(二)
    Linux基础(一)
    代码自动生成
    luaScript目标点限流工具类示例
    SpringMVC请求连接匹配器-工具类
    解决commons.mail.HtmlEmail附件中文名乱码问题
    HtmlToPdfUtils [请参照码云上 https://gitee.com/bbevis/html-to-pdf 最新版]
    ThreadLocalUtils
  • 原文地址:https://www.cnblogs.com/makai/p/15494123.html
Copyright © 2011-2022 走看看