ThreadLocal不好用?那是你没用对!(4)

简介: ThreadLocal不好用?那是你没用对!(4)

a) 线程安全问题分析


为了找到问题所在,我们尝试查看 SimpleDateFormatformat 方法的源码来排查一下问题,format 源码如下:


private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
    // 注意此行代码
    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.format 方法时,会使用 calendar.setTime 方法将输入的时间进行转换,那么我们想想一下这样的场景:


  1. 线程 1 执行了 calendar.setTime(date) 方法,将用户输入的时间转换成了后面格式化时所需要的时间;


  1. 线程 1 暂停执行,线程 2 得到 CPU 时间片开始执行;


  1. 线程 2 执行了 calendar.setTime(date) 方法,对时间进行了修改;


  1. 线程 2 暂停执行,线程 1 得出 CPU 时间片继续执行,因为线程 1 和线程 2 使用的是同一对象,而时间已经被线程 2 修改了,所以此时当线程 1 继续执行的时候就会出现线程安全的问题了。


正常的情况下,程序的执行是这样的:


微信图片_20220120184505.jpg


非线程安全的执行流程是这样的:


微信图片_20220120184537.jpg

相关文章
|
存储 机器学习/深度学习 缓存
我惊了!!!ThreadLocal 源码存在内存泄露的 Bug!!!
我惊了!!!ThreadLocal 源码存在内存泄露的 Bug!!!
151 0
|
存储 消息中间件 JavaScript
ThreadLocal 你真的用不上吗?
ThreadLocal 你真的用不上吗?
|
存储 缓存 Java
终于弄明白了ThreadLocal
ThreadLocal是Thread的局部变量,用于编多线程程序,对解决多线程程序的并发问题有一定的启示作用。
160 0
终于弄明白了ThreadLocal
|
算法 C++
没什么。。。。
没什么。。。。
J3
|
存储 安全 Java
synchronized解析及锁膨胀过程,面试再也不怕了
synchronized解析及锁膨胀过程,面试再也不怕了
J3
540 0
synchronized解析及锁膨胀过程,面试再也不怕了
ThreadLocal不好用?那是你没用对!(7)
ThreadLocal不好用?那是你没用对!(7)
86 0
ThreadLocal不好用?那是你没用对!(7)
ThreadLocal不好用?那是你没用对!(10)
ThreadLocal不好用?那是你没用对!(10)
89 0
ThreadLocal不好用?那是你没用对!(10)
ThreadLocal不好用?那是你没用对!(8)
ThreadLocal不好用?那是你没用对!(8)
113 0
ThreadLocal不好用?那是你没用对!(8)
|
存储 对象存储
ThreadLocal不好用?那是你没用对!(13)
ThreadLocal不好用?那是你没用对!(13)
129 0
ThreadLocal不好用?那是你没用对!(13)
|
Java
ThreadLocal不好用?那是你没用对!(1)
ThreadLocal不好用?那是你没用对!(1)
137 0
ThreadLocal不好用?那是你没用对!(1)