首页 > 代码库 > 【原创】源码角度分析Android的消息机制系列(二)——ThreadLocal的工作过程

【原创】源码角度分析Android的消息机制系列(二)——ThreadLocal的工作过程

ι 版权声明:本文为博主原创文章,未经博主允许不得转载。

在上一篇文章中,我们已经提到了ThreadLocal,它并非线程,而是在线程中存储数据用的。数据存储以后,只能在指定的线程中获取到数据,对于其他线程来说是无法获取到数据的,也就是说ThreadLocal可以在多个线程中互不干扰地存储和修改数据。基于ThreadLocal的这一特点,那么当我们在开发中,需要将某些数据以线程作为作用域,并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal了。

Android的消息机制中也用到了ThreadLocal。Handler需要获取到当前线程的Looper,但是不同线程中的Looper是不同的,此时就可以通过ThreadLocal来实现Looper在线程中的存取了。

下面通过例子来观察下ThreadLocal存储数据的特点。

首先定义一个ThreadLocal对象,然后分别在主线程,子线程1和子线程2中设置和访问它的值,代码如下所示:

    private final String TAG=getClass().getSimpleName(); //获取当前类名
    private ThreadLocal<Boolean> mBooleanThreadLocal=new ThreadLocal<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mBooleanThreadLocal.set(true);
        Log.e(TAG, "[mainThread]mBooleanThreadLocal="+mBooleanThreadLocal.get() );
 
        new Thread("Thread1"){
            @Override
            public void run() {
                super.run();
                mBooleanThreadLocal.set(false);
                Log.e(TAG, "[Thread1]mBooleanThreadLocal="+mBooleanThreadLocal.get() );
            }
        }.start();
 
        new Thread("Thread2"){
            @Override
            public void run() {
                super.run();
                Log.e(TAG, "[Thread2]mBooleanThreadLocal="+mBooleanThreadLocal.get() );
            }
        }.start();
    }

日志如下所示:

06-17 16:46:04.663 5300-5300/com.bella.androidart E/ThreadLocalActivity: [mainThread]mBooleanThreadLocal=true
06-17 16:46:04.663 5300-5317/com.bella.androidart E/ThreadLocalActivity: [Thread1]mBooleanThreadLocal=false
06-17 16:46:04.679 5300-5318/com.bella.androidart E/ThreadLocalActivity: [Thread2]mBooleanThreadLocal=null

从上面日志可以看出,虽然在不同线程中访问的是同一个ThreadLocal对象,但是它们通过ThreadLocal获取到的值却是不一样的,这就是ThreadLocal的奇妙之处。ThreadLocal之所以有这么奇妙的效果,是因为不同线程访问同一个ThreadLocal的get方法,ThreadLocal内部会从各自的线程中取出一个数组,然后再从数组中根据当前ThreadLocal的索引去查找出对应的value值。很显然,不同线程中的数组是不同的。

      

【原创】源码角度分析Android的消息机制系列(二)——ThreadLocal的工作过程