• 右耳听海
    2019-05-07
    有个疑问请教老师,避免共享变量的两种解决方案,在高并发情况下,使用局部变量会频繁创建对象,使用threadlocal也是针对线程创建新变量,都是针对线程维度,threadlocal并未体现出什么优势,为什么还要用threadlocal

    作者回复: threadlocal=线程数,局部变量=调用量,差距太大了

     3
     42
  • 晓杰
    2019-05-07
    不可以,因为ThreadLocal内的变量是线程级别的,而异步编程意味着线程不同,不同线程的变量不可以共享

    作者回复: 👍

    
     32
  • QQ怪
    2019-05-07
    上面有些同学说多线程是simpledateformat会打印出一样名称的对象,我刚刚也试了下,的确可以复现,但其实是simpledateformat对象的toString()方法搞得鬼,该类是继承object类的tostring方法,如下有个hashcode()方法,但该类重写了hashcode方法,在追溯到hashcode方法,pattern.hashcode(),pattern就是我们的yyyy-MM-dd,这个是一直保持不变的,现在终于真相大白了

    作者回复: 感谢回复!!!!

    
     19
  • 承香墨影
    2019-05-22
    老师您好,有个问题想请教。
    在线程池中使用 ThreadLocal,您给的解决方案是,使用后手动释放。
    那这样和使用线程的局部变量有什么区别?每次线程执行的时候都去创建对象并存储在 ThreadLocal 中,用完就释放掉了,下次执行依然需要重新创建,并存入 ThreadLocalMap 中,这样并没有解决局部变量频繁创建对象的问题。

    作者回复: 这种用法一般是为了在一个线程里传递全局参数,也叫上下文信息,局部变量不能跨方法,这个用法不是用来解决局部变量重复创建的

    
     11
  • 峰
    2019-05-07
    java实现异步的方式基本上就是多线程了,而threadlocal是线程封闭的,不能在线程之间共享,就谈不上全局的事务管理了。
    
     10
  • linqw
    2019-05-25
    自己写了下对ThreadLocal的源码分析https://juejin.im/post/5ce7e0596fb9a07ee742ba79,感兴趣的可以看下哦,老师也帮忙看下哦

    作者回复: 有心👍

    
     6
  • GEEKBANG_6638780
    2019-06-12
    @vic
    想问一下如果gc发生在对threadLocal的 set和get操作之间,get的时候value对应的key已经被gc了,不是拿不到我之前放进threadLocal的对象了吗?这样对业务不会有问题吗?
    ---------------------------------
    是的,一般建议threadlocal采用static修饰,而且遵循try finally编程
    
     3
  • 晓杰
    2019-05-07
    请问一下老师,我刚刚对simpledateformat加threadlocal,但是不同线程得到的simpledateformat对象是一样的,代码如下:
    public class Tool {
        public static void main(String[] args) throws Exception{
            System.out.println(SafeDateFormat.get());
            System.out.println(Thread.currentThread().getName());
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                    System.out.println(SafeDateFormat.get());
                }
            }).start();

        }

        static class SafeDateFormat{
            static final ThreadLocal<SimpleDateFormat> sdf =
                    ThreadLocal.withInitial(()->new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            static SimpleDateFormat get(){
                return sdf.get();
            }
        }
    }
    请问存在什么问题
    展开

    作者回复: 有同学已经找到原因了,是tostring的锅

    
     3
  • So
    2019-09-11
    一个ThreadLocal只能保存一个变量,那如果有多个变量要保存,是不是要建多个ThreadLocal?

    作者回复: 是的

    
     2
  • ddup
    2019-05-16
    System.identityHashCode(dateFormat)); 这个来打印内存地址。
    
     2
  • 刘晓林
    2019-05-11
    getEntry(): 0x61c88647,解决hash碰撞的一个神奇的数
    
     2
  • lik
    2019-05-07
    想问一下如果gc发生在对threadLocal的 set和get操作之间,get的时候value对应的key已经被gc了,不是拿不到我之前放进threadLocal的对象了吗?这样对业务不会有问题吗?
    
     2
  • 张三
    2019-05-07
    打卡!我认为不行吧,文末提到ThreadLocal创建的线程变量子线程无法继承了。
    
     2
  • xinglichea
    2019-08-26
    老师,
    文中提到解决内存泄露的方法是显示调用remove()方法,但貌似ThreadLocalMap的设计中已经考虑到这种情况,也加上了一些防护措施:在ThreadLocal的get(),set(),remove()的时候都会清除线程ThreadLocalMap里所有key为null的value,即:在ThreadLocalMap中的setEntry()、getEntry(),如果遇到key == null的情况,会对value设置为null。

    那么是不是可以说明,如果线程在后续操作中会继续调用set()、get()的话,就不需要显示调用remove()了。
    展开

    作者回复: 工程上建议不要做假设,万一出了问题不好查

    
     1
  • 拯救地球好累
    2019-07-28
    ---启发---
    老师对ThreadLocal的思考上,让我对理解一个类的设计问题上有所启发。对一个类的实例、方法等的设计,除了功能上的考虑外,也要考虑安全性、性能问题,也可以站在抽象的角度思考其逻辑。

    作者回复: 👍

    
     1
  • 盐多必失
    2019-06-09
    某山东省主席…… 宝令小哥哥这加密算法做得太好了,^_^

    作者回复: 大智若愚,谁说的清呢,一起鄙视那些不加密的吧😄

    
     1
  • 看不到de颜色
    2019-05-19
    异步编程应该慎用ThreadLocal。因为不再是同一个线程执行,所以获取不到原本想获取的数据
    
     1
  • 天天向善
    2019-05-08
    有个疑问请教,线程多路复用,使用thread local有什么注意的,会不会不同请求获取内容相同,造成后续业务错误

    作者回复: 很有这种可能,所以不能用它存状态数据

     1
     1
  • QQ怪
    2019-05-07
    扩展:可以打断点进ThreadLocal的getmap方法里面可以直接看到slf对象是不同的
    
     1
  • 张三
    2019-05-07
    这节的ThreadLocal,我记得15年刚开始工作的时候,工作中有一个需要动态切换数据源的需求,Spring+Hibernate框架,当时通过百度查到用ThreadLocal,使用AOP在进入service层之前来切换数据源。正好跟这里文章说的Spring使用ThreadLocal来传递事物信息意思一样吧。
    
     1
我们在线,来聊聊吧