ThreadLoacl类解析
来源:互联网 发布:域名ns记录查询 编辑:程序博客网 时间:2024/05/29 16:18
ThreadLocal 类的解析:
类继承关系
java.lang.Object
java.lang.ThreadLocal
官方描述:
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量。ThreadLocal 在类声明为private static作为类成员变量来使用。
ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储的数据,对于其它线程来说无法获取到数据。Android的源码中Looper也用到了ThreadLocal。,当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal。
比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以实现Looper在线程中的存取,。
简单的例子:
类内部成员变量
private ThreadLocal threadLocal
= new ThreadLocal();
//主线程调用Set()
threadLocal.set(true);
Log.w(“Tag”, “mainThread:” + threadLocal.get());
new Thread(){
@Override
public void run() {
//子线程调用Set()
threadLocal.set(false);
Log.w(“Tag”, “childThread1:” + threadLocal.get());
}
}.start();
new Thread(){
@Override
public void run() {
//子线程直接取值,
Log.w(“Tag”, “childThread2:” + threadLocal.get());
}
}.start();
结果:
可以看到,在不同线程中访问同一个ThreadLocal 对象,但是通过ThreadLocal取到的值是不一样的
主线程 和 第一个子线程,取得了各自set进去的对象的值,第二个子线程 因为没有值,获得null
成员
简单看下ThreadLocal类的组成,有set() ,get()方法
:
THreadLocal 有个内部类Values类。
Values是ThreadLocal的静态成员内部类, 这个类内部有个成员变量table,
类型为Object[],Values内部的方法add(),put(),..等方法其实就是在操作这张表。
而查看Thread类可以看到有个成员变量
可以知道Values的作用就是用来存储线程的ThreadLocal 数据
简单分析下ThreadLocal的set方法,
取到该线程的内部成员values, 调用put方法,
简单查看下Value的put方法
可以看出如果ThreadLocal的reference对象在table数组中的位置是index,那么THreadLocal的值在table数组中的索引就是index+1,最终的值也就保存在table[index+1]中了
现在,再看下ThreadLocal 类 get()方法的流程
1.获得当前的线程
2.根据当前的线程,获得线程的Thread.Values类型的成员
3.如果该values不为空,则以ThreadLocal 自身的引用作为key来在table中获取对应的值
4.如果values为空,以该线程为参数 初始化values, 以 ThreadLocal自身的引用作为key,默 认值null作为value,调用put方法保存一个默认值。返回该值
了解了ThreadLocal,再来看Looper 是如何实现 在每个线程中得到该线程对应的Looper
Looper类有个静态成员变量 ThreadLocal sThreadLocal
我们都知道android中 在非主线程默认是没有Looper的,需要先调用Looper.prepare(),
Prepare()调用了带参数的prepare(true)方法,在这个方法中,创建了Loop,并调用静态成员
sThreadLocal的set方法,将自身存入。
可以看到 如果多次调用,prepare()方法,将会抛出异常 Only one Looper may be ……
要获得该线程对应的Looper ,只要在该线程内调用
就可以取到了。
要取到主线程的Looper,在子线程内直接调用getMainLooper(),
sMainLooper这个成员变量是由系统初始化化的。系统通过调用prepareMainLooper() 初始化主线程的Looper,
文档中指明了这个方法用户永远不需要调用。
- ThreadLoacl类解析
- java中ThreadLoacl解析
- Java的ThreadLoacl类
- ThreadLoacl源码解读
- ThreadLoacl那些事儿
- JDK学习-ThreadLoacl
- ThreadLoacl的作用及使用
- 第三章ThreadLoacl的使用
- 类解析
- XML文件解析工具类pull解析
- Log4j源码解析--核心类解析
- Log4j源码解析--Layout类解析
- jdk工具类____xml解析SAX解析
- jdk工具类____xml解析Dom解析
- 深入解析jvm 类加载器解析
- JAVA JSON解析:类XPATH解析JSON
- 解析HTML的类
- ConfigurationSettings类解析
- NSObject--NSDate常用方法
- [MySQL FAQ]系列 — 线上环境到底要不要开启query cache
- 纸上谈兵: 树, 二叉树, 二叉搜索树
- 【NOIP复习】【数学】
- HttpClient连接池使用
- ThreadLoacl类解析
- 如何将自定义的三方库加入到cocoapods中管理
- 如何调整IMindMap思维导图大小位置
- Django快速开发之投票系统
- java范型之--通配符
- Android Studio新建内置模拟器
- 在使用cppunit,搭建测试环境时遇到的问题以及解决办法(仅供参考)
- 杭电2180时钟
- NSData