Android开发——ThreadLocal功能介绍
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功能介绍的更多相关文章
- Android开发——Viewpager的介绍使用
目录: 一.Viewpager的简单介绍 二.简单的Viewpager使用 三.简单显示图片的Viewpager实现 四.广告图的实现及Viewpager指示器(小圆点)的实现 五.APP引导页的实现 ...
- Android开发教程大全介绍
Android是由谷歌在2007年推出的一个开放系统平台,主要针对移动设备市场,目前版本为Android 4.0.Android基于Linux,开发者可以使用Java或C/C++开发Android应用 ...
- Android开发---支付宝功能接口(支付功能)(转载!)
最近在做一个关于购物商城的项目,项目里面付款这块我选的是调用支付宝的接口,因为用的人比较多. 在网上搜索了以下,有很多这方面的教程,但大部分教程过于陈旧,而且描述的过于简单.而且支付宝提供的接口一直在 ...
- IBOS云办公系统二次开发之功能介绍(PHP技术)
IBOS自动化办公系统是我见到的功能.架构最好的开源自动化办公系统,功能与企业需求吻合度之高.架构之灵活,让我不得不将之介绍给大家,让跟多需要学习PHP开发的朋友来了解她,拥抱她! 如果您还没有很好的 ...
- Android 开发 倒计时功能 转载
原文地址:https://www.cnblogs.com/xch-yang/p/7920419.html Android为我们封装好了一个抽象类CountDownTimer,可以实现计时器功能: /* ...
- 【Android】Android开发小功能,倒计时的实现。时间计时器倒计时功能。
作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先给大家看一下我们今天这个最终实现 ...
- entfrm-boot开发平台功能介绍【entfrm开源模块化无代码开发平台】
简介 entfrm开发平台,是一个以模块化为核心的无代码开发平台,是一个集PC和APP快速开发.系统管理.运维监控.开发工具.OAuth2授权.可视化数据源管理与数据构建.API动态生成与统计.工作流 ...
- Android Studio 简单功能介绍
Android Studio 建立系统工具包你用来生成,测试,运行您的应用程序和软件包.构建系统是独立于Android的工作室,所以你可以调用它的Android的工作室或从命令行.在你写你的应用程序 ...
- Android开发——Android的消息机制详解
)子线程默认是没有Looper的,Handler创建前,必须手动创建,否则会报错.通过Looper.prepare()即可为当前线程创建一个Looper,并通过Looper.loop()来开启消息循环 ...
随机推荐
- [已读]用Angularjs开发下一代web应用
屯了很久了,貌似是国内出现的第一本讲angularjs的书...上上周看完的时候,angular2都要出来了...angular的双向绑定很赞,因为之前公司后台系统我都用tmodjs做,模板语法什么的 ...
- HashMap源码及原理
HashMap 简介 底层数据结构分析 JDK1.8之前 JDK1.8之后 HashMap源码分析 构造方法 put方法 get方法 resize方法 HashMap常用方法测试 感谢 changfu ...
- 关于Winform控件调用插入点(光标)的用法
我们自定义控件中可能会有一些光标的使用,比如插入文字和图片提示,下面是调用WIN32 API的光标用法 Winform控件调用插入点的用法 // 导入处理光标的 Windows 32 位 API // ...
- Java基础之面向对象
面向对象 1.面向对象思想: (1)概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象,强调具备功能的对象: (2)思想特点: ...
- python第一模块数据类型
一·进制之间的转换 十进制转换为二进制:逆序取余法. 二进制转换为十进制:如1101 1*2^0 + 0*2^1 + 1*2^2 +1 十六进制转换为二进制:231 0010 0011 ...
- 洛谷 P1376 机器工厂
题目描述 小T开办了一家机器工厂,在N(N<=10000)个星期内,原材料成本和劳动力价格不断起伏,第i周生产一台机器需要花费Ci(1<=Ci<=5000)元.若没把机器卖出去,每保 ...
- UVA - 1395 Slim Span (最小生成树Kruskal)
Kruskal+并查集. 点很少,按边权值排序,枚举枚举L和R,并查集检查连通性.一旦连通,那么更新答案. 判断连通可以O(1),之前O(n)判的,第一次写的过了,后来T.. #include< ...
- Vue v-if与v-show的区别
用了 viewjs 预览图片的时候 发现 用着两个 还是有区别的, 相同点==== v-if与v-show都可以动态控制dom元素显示隐藏 不同点 = ====v-if显示隐藏是将dom元素整个添加 ...
- file-leak-detector(文件句柄泄漏)在JDK1.6环境下 weblogic 和 tomcat安装方式以及使用方式
file-leak-detector作者博客详见: http://file-leak-detector.kohsuke.org/ file-leak-detector学习贴: https://blog ...
- python常用模块之requests
一.requests 1.GET url带参数请求 >>> payload = {'key1': 'value1', 'key2': 'value2'} >>> ...