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

在上一篇文章中,我们已经提到了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的工作过程的更多相关文章

  1. 【原创】源码角度分析Android的消息机制系列(五)——Looper的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. Looper在Android的消息机制中就是用来进行消息循环的.它会不停地循环,去MessageQueue中查看是否有新消息,如果有消息就立刻 ...

  2. 【原创】源码角度分析Android的消息机制系列(六)——Handler的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Handler的定义: /** * A Handler allows you to send and process {@link Mes ...

  3. 【原创】源码角度分析Android的消息机制系列(一)——Android消息机制概述

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.为什么需要Android的消息机制 因为Android系统不允许在子线程中去访问UI,即Android系统不允许在子线程中更新UI. 为什 ...

  4. 【原创】源码角度分析Android的消息机制系列(三)——ThreadLocal的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看Android源码(API24)中对ThreadLocal的定义: public class ThreadLocal<T> 即 ...

  5. 【原创】源码角度分析Android的消息机制系列(四)——MessageQueue的工作原理

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. MessageQueue,主要包含2个操作:插入和读取.读取操作会伴随着删除操作,插入和读取对应的方法分别为enqueueMessage和ne ...

  6. 源码角度分析-newFixedThreadPool线程池导致的内存飙升问题

    前言 使用无界队列的线程池会导致内存飙升吗?面试官经常会问这个问题,本文将基于源码,去分析newFixedThreadPool线程池导致的内存飙升问题,希望能加深大家的理解. (想自学习编程的小伙伴请 ...

  7. Android的Message Pool是什么——源码角度分析

    原文地址: http://blog.csdn.net/xplee0576/article/details/46875555 Android中,我们在线程之间通信传递通常采用Android的消息机制,而 ...

  8. Android -- 带你从源码角度领悟Dagger2入门到放弃(二)

    1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...

  9. 【react】什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行

    壹 ❀ 引 我在[react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?一文中,介绍了虚拟dom的概念,以及react中虚拟dom的使用场景 ...

随机推荐

  1. python2与python3的区别 ,小数据池 bytes 类型

    一.python2和3的区别 在python3中 在python2中 print('ab')方式打印内容()括号是必须要有的.   print 'ab' 可以加可以不加. 只有range   有ran ...

  2. POJ3041-Asteroids-匈牙利算法

    Asteroids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23963   Accepted: 12989 Descr ...

  3. BZOJ3930: [CQOI2015]选数

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3930 容斥原理. 令l=(L-1)/k,r=R/k,这样找k的倍数就相当于找1的倍数. 设F[ ...

  4. c++工程重复编译与重复定义

    #ifndef #define #endif防止的是"重复编译",而不是"重复定义"重复编译可能造成重复定义,但重复定义的来源不只有重复编译从代码变成可执行的程 ...

  5. C#的改进特性

    1.初始器 当你新建一个对象实例的时候,是否遇到下面这种情况: class a = new class(); a.item1 = "; a.item2 = "; 或者写一个构造函数 ...

  6. mysql 恢复数据

    前提:保存了需要恢复数据库的文件 .frm 和 .ibd 文件 条件:InnoDB 类型的 恢复表结构1.新建一个数据库--新建一个表,表名和列数和需要恢复数据库相同2.停止mysql服务器 serv ...

  7. 图解vue生命周期

    学习vue时搞清楚生命周期可以帮助你知道什么时候在什么地方执行该执行的方法,话不多说上图: 复制下面代码可以在控制台更详细展示各个钩子的状态 <!DOCTYPE html> <htm ...

  8. Oracle实战笔记(第三天)

    导读 今天的主要内容有:java连接Oracle.事务.Oracle中的事务处理.Oracle函数. 一.Java连接Oracle的两种方式 第一种:桥连接(JDBC_ODBC)(不推荐) 1.准备工 ...

  9. [国嵌攻略][065][DM9000驱动程序设计]

    移植代码:通过已有的可用的代码修改到新环境下运行. 代码编写: 初始化网卡 1.选中网卡 nLAN_CS BWSCON(0x48000000) DW4:01 16bit BANKCON4(0x4800 ...

  10. [国嵌笔记][013][Mini2440开发板介绍]

    系统资源 处理器:三星 S3C2440A ARM9 内存:64M SDRAM Nor Flash:2MB Nand  Flash:256MB LCD:3.5寸 分辨率320*240 启动模式 从nan ...