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!!!
117 0
|
存储 消息中间件 JavaScript
ThreadLocal 你真的用不上吗?
ThreadLocal 你真的用不上吗?
|
存储 缓存 Java
终于弄明白了ThreadLocal
ThreadLocal是Thread的局部变量,用于编多线程程序,对解决多线程程序的并发问题有一定的启示作用。
147 0
终于弄明白了ThreadLocal
|
Java
如何避免忘记清理 ThreadLocal ?
hreadLocal 可以解决“线程安全问题”。 也可以作为上下文暂存数据以备后续步骤获取。 但是 ThreadLocal 用不好的确容易产生故障,因而有些团队不允许使用 ThreadLocal。 最核心的一个原因是很容易忘记清理,在线程池环境下复用导致串环境。 那么,有什么优雅的解法没?本文给出自己的一个解法。
731 0
如何避免忘记清理 ThreadLocal ?
ThreadLocal不好用?那是你没用对!(7)
ThreadLocal不好用?那是你没用对!(7)
84 0
ThreadLocal不好用?那是你没用对!(7)
|
存储 对象存储
ThreadLocal不好用?那是你没用对!(13)
ThreadLocal不好用?那是你没用对!(13)
121 0
ThreadLocal不好用?那是你没用对!(13)
ThreadLocal不好用?那是你没用对!(11)
ThreadLocal不好用?那是你没用对!(11)
104 0
ThreadLocal不好用?那是你没用对!(11)
ThreadLocal不好用?那是你没用对!(2)
ThreadLocal不好用?那是你没用对!(2)
94 0
ThreadLocal不好用?那是你没用对!(2)
|
安全
ThreadLocal不好用?那是你没用对!(5)
ThreadLocal不好用?那是你没用对!(5)
101 0
ThreadLocal不好用?那是你没用对!(5)
|
Java
ThreadLocal不好用?那是你没用对!(1)
ThreadLocal不好用?那是你没用对!(1)
126 0
ThreadLocal不好用?那是你没用对!(1)