简谈Thread Local工作原理

简谈Thread Local工作原理

  • 什么是Thread Local?

    • Thread Local 是一个线程内部的数据存储类,每一个线程都维护一个table[],通过set(),get()方法实现存取操作。

    • 只能在指定的线程中获取存储的数据,其他的线程一般无法获取。(注意:这里我用的是一般,可以使用InheritableThreadLocal达到其他线程获取数据的)

  • 什么情况下使用Thread Local呢?

    • 一般来说,当某些数据以线程为作用域并且不同线程具有不同的数据副本时,就考虑用它了

    • 典型的例子是:Handler要获取当前线程的Looper,Looper的作用域为线程,每个线程具有不同的Looper.

Thread Local的使用方法

   private void testThreadLocal() {
    new Thread(new Runnable() {
        //创建ThreadLocal 对象,支持泛型
        ThreadLocal<String> mLocal = new ThreadLocal<String>();
        @Override
        public void run() {
            mLocal.set("Fan Bin Bin is nice!");
            String s = mLocal.get();
            Log.i("TAG", s);
        }
    }).start();
}

打印结果:
threadlocaltest I/TAG: Fan Bin Bin is nice!

有一个特殊的例子可以实现不同线程的访问存储变量

  private void testThreadLocal() {
    final ThreadLocal<String> local = new InheritableThreadLocal<>();
    local.set("I love China");
    new Thread(new Runnable() {
        @Override
        public void run() {
            Log.i("TAG", local.get() + "");
        }
    }).start();
}

打印结果:

com.yutianwang.threadlocaltest I/TAG: I love China

这里在主线程中创建了InheritableThreadLocal对象,居然在子线程中能够打印出这句话,实现原理大致是:当子线程创建的时候,主线程会将InheritableThreadLocal对象传递给子线程中去,所以能够打印这句话。

这里写图片描述

LocalValues内部有个数组:private Object[] table,Thread local的值就存储在这个table数组中
这里写图片描述

取出当前线程LocalValues对象,如果为null,返回初始值,如果不为空,从table数组中取出Thread Local值

总结

Thread Local所做的读写操作仅限于各自线程的内部,所以在多个线程中互补干扰的存储和修改数据。

声明

此文是建立在《Android开发艺术探索》和

http://droidyue.com/blog/2016/03/13/learning-threadlocal-in-java/
这篇文章基础上的读书笔记。(PS:准大三狗真是累!hh)

发布了49 篇原创文章 · 获赞 66 · 访问量 6万+
展开阅读全文

关于threadLocal的疑惑

06-03

最近在看ThreadLocal的底层实现,通过查看源码发现此类主要的核心是通过获取到当前运行线程的一个变量threadLocals来为每一个线程提供一个本地存储。本人在网上看到很多对ThreadLocal讲解的帖子,一直不是特别理解他们说的副本是什么意思,为什么不会被其他线程干扰,是一个对象的深拷贝吗?但是在ThreadLocal中的set方法中也只是一个this.value=value;所以如果把同一个对象放入不同的两个线程的ThreadLocal中,其中一个线程对该对象的字段进行修改,其实是会影响到另一线程中的对象的。本人测试的结果也是如此。 ``` public class MyThreadLocalTest { public static void main(String[] args) throws InterruptedException { ThreadLocal threadLocal = new ThreadLocal(); ThreadLocal threadLocal2 = new ThreadLocal(); Student a = new Student(); threadLocal2.set(a); a.setName("mainThread"); new Thread(( () -> { threadLocal.set(a); ((Student) (threadLocal.get())).setName("myThread"); System.out.println("myThread 学生:" + threadLocal.get()); } )).start(); //这里睡十秒 不然的话有可能主线程先执行 Thread.sleep(10000); System.out.println("mainThread学生:" + threadLocal2.get()); } } ``` ![图片说明](https://img-ask.csdn.net/upload/201906/03/1559531267_117114.png) 本人在网上看到很多帖子以hibernate的session举例,但是本人只能理解到这个threadLocal只能保证到每个线程获取到同一个session对象而已,并不能解决多个线程拿到同一session后如果closs掉以后其他线程的session不被影响,希望大牛给予指点 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览