1.使用场景以及作用介绍

(1)ThreadLocal适用于某些数据以线程为作用域并且不同线程具有不同数据副本的场景。

比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。

(2)ThreadLocal的另一个使用场景是复杂逻辑下的对象传递。

比如监听器的传递,有时一个线程中的任务过于复杂,又需要监听器贯穿整个线程的执行过程,这时就可以使用ThreadLocal,这样就可以让监听器作为线程内的全局对象而存在,在线程内部只要通过get方法就可以获取到监听器。每个监听器对象都在自己的线程内部存储。

如果不这样做,我们可能将监听器作为函数参数传递,但是这样会很麻烦,降低代码的可读性。或者我们会将监听器作为静态变量供线程访问,但是100个线程就需要100个静态的监听器对象,显然是无法接受的。

2.  使用实例

//首先定义一个ThreadLocal对象,选择泛型为Boolean类型
private ThreadLocal<Boolean> mThreadLocal = new ThreadLocal<Boolean>(); //在主线程、子线程1、子线程2中去设置访问它的值
mThreadLocal.set(true);
System.out.println("Main " + mThreadLocal.get()); new Thread("Thread#1"){
@Override
public void run() {
mThreadLocal.set(false);
System.out.println("Thread#1 " + mThreadLocal.get());
}
}.start(); new Thread("Thread#2"){
@Override
public void run() {
System.out.println("Thread#2 " + mThreadLocal.get());
}
}.start();

输出结果如下:

Main true
Thread#1 false
Thread#2 null


3.  原理介绍

不同的线程访问同一个ThreadLocal获取到的值是不一样的,这是因为,在set方法中,首先通过Thread.currentThread()获取当前线程,Thread类的内部有一个专门用于存储线程ThreadLocal数据的成员Value,通过下面方法获得。

Value value = values(Thread.currentThread());

拿到value后,value对象内部有一个数组:private Object[]table,ThreadLocal的值就存在这个table中,最后通过value的put方法,将最初set方法传递进来的值,根据一定的算法放入table数组中。取数据则通过get方法,依据算法的逆来获取。

set方法源码如下,get源码略。

public void set(T value){
Thread currentThread = Thread.currentThread();
Value values = values(currentThread);
if(values == null){
//初始化操作
values = initializeValues(currentThread);
}
values.put(this,value);
}

总结:ThreadLocal的set和get操作,对象都是当前线程的Value类实例中的table数组,显然不同线程,数组不同,因此ThreadLocal可以在多线程中互不干扰地存储和修改数据。

Android开发——ThreadLocal功能介绍的更多相关文章

  1. Android开发——Viewpager的介绍使用

    目录: 一.Viewpager的简单介绍 二.简单的Viewpager使用 三.简单显示图片的Viewpager实现 四.广告图的实现及Viewpager指示器(小圆点)的实现 五.APP引导页的实现 ...

  2. Android开发教程大全介绍

    Android是由谷歌在2007年推出的一个开放系统平台,主要针对移动设备市场,目前版本为Android 4.0.Android基于Linux,开发者可以使用Java或C/C++开发Android应用 ...

  3. Android开发---支付宝功能接口(支付功能)(转载!)

    最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...

  4. IBOS云办公系统二次开发之功能介绍(PHP技术)

    IBOS自动化办公系统是我见到的功能.架构最好的开源自动化办公系统,功能与企业需求吻合度之高.架构之灵活,让我不得不将之介绍给大家,让跟多需要学习PHP开发的朋友来了解她,拥抱她! 如果您还没有很好的 ...

  5. Android 开发 倒计时功能 转载

    原文地址:https://www.cnblogs.com/xch-yang/p/7920419.html Android为我们封装好了一个抽象类CountDownTimer,可以实现计时器功能: /* ...

  6. 【Android】Android开发小功能,倒计时的实现。时间计时器倒计时功能。

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先给大家看一下我们今天这个最终实现 ...

  7. entfrm-boot开发平台功能介绍【entfrm开源模块化无代码开发平台】

    简介 entfrm开发平台,是一个以模块化为核心的无代码开发平台,是一个集PC和APP快速开发.系统管理.运维监控.开发工具.OAuth2授权.可视化数据源管理与数据构建.API动态生成与统计.工作流 ...

  8. Android Studio 简单功能介绍

    Android Studio  建立系统工具包你用来生成,测试,运行您的应用程序和软件包.构建系统是独立于Android的工作室,所以你可以调用它的Android的工作室或从命令行.在你写你的应用程序 ...

  9. Android开发——Android的消息机制详解

    )子线程默认是没有Looper的,Handler创建前,必须手动创建,否则会报错.通过Looper.prepare()即可为当前线程创建一个Looper,并通过Looper.loop()来开启消息循环 ...

随机推荐

  1. linux 设置固定IP centOS6.5

    主要是要把Linux的IP固定下来,可以用另一台机器SSH连接. ping的用法: 基本语法:ping [-选项] IP地址或域名 功能描述:测试网络是否连通 常用选项:-c -c 指定发送数据包的次 ...

  2. axios delete 请求

    axios delete 请求 在传递一个参数的时候,直接把参数放在请求连接后面,用'/' 连接就可以了 this.axios.post(this.APIURL+'/'+ID) //http://ww ...

  3. SSAS中雪花模型

    上面的[销售事实表]与[门店]维度.[集团]维度就组成了一个雪花模型. 1.可以把[集团]关联到[门店]的维度上去: 2.如果要把[集团]作为一个单独的维度,先在[维度]里把Dim_Group添加进来 ...

  4. C# 连接 Oracle,读取Blob字段数据,存到文件中去,包括pdf等等

    代码如下,记得引入Oracle的dll using System; using System.Collections.Generic; using System.ComponentModel; usi ...

  5. ES-Mac OS环境搭建-kibana

    简介 Kibana是一个为ElasticSearch 提供的数据分析的 Web 接口.可使用它对日志进行高效的搜索.可视化.分析等各种操作. 下载 打开elasticseach官网,单击downloa ...

  6. APP产品体验

    一.前言   1.背景介绍 体验人员:羽珞体验时间:2016.4.12~2016.4.14   2.体验环境 产品名称 产品版本 测试设备 设备系统 易助(ehlep) 1.0 TCL J738M A ...

  7. Android程序中使用iconfont心得

    1.关于iconfont iconfont既是icon又是font,具体来说应该是用font形式展现的icon.与传统图片格式的图标不同,这一种图标因为是以字体形式展现的,所以更改大小.颜色.背景颜色 ...

  8. php关于精准计算的模块 BCMath

    Php: BCMath bc是Binary Calculator的缩写.bc*函数的参数都是操作数加上一个可选的 [int scale],比如string bcadd(string $left_ope ...

  9. HDOJ1195 双向BFS //单向也可以过 没想清

    #include<cstdio> #include<map> #include<vector> #include<stack> #include< ...

  10. java实现中文或其他语言及标点符号等转换成unicode字符串,或unicode的16进制码转换回文字或符号等

    package org.analysisitem20181016.test; public class Code128Test2019052201 { public static final Stri ...