一 ThreadLocal的简介
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).
以上是摘抄于java中的ThreadLocal.java中的解释.
概意有如下几点(英文不是很好,抱歉)
- ThreadLocal这个类提供线程本地变量
- 每个线程可以通过get()或者set()得到或设置自己拥有的变量,且不相互映像
我们通过实例简单测试一下:
//private ThreadLocal<String> mThreadLocal = new ThreadLocal<>();
mThreadLocal.set(Thread.currentThread().getName()); //保存当前主线程的名字
Log.d(TAG, "----Thread#main------mThreadLocal.get():" + mThreadLocal.get());
new Thread("Thread#1") {
@Override
public void run() {
super.run();
//保存线程1中的名字
mThreadLocal.set(Thread.currentThread().getName());
Log.d(TAG, "----Thread#1------mThreadLocal.get():" + mThreadLocal.get());
}
}.start();
new Thread("Thread#2") {
@Override
public void run() {
super.run();
//保存线程2中的名字
mThreadLocal.set(Thread.currentThread().getName());
Log.d(TAG, "----Thread#2------mThreadLocal.get():" + mThreadLocal.get());
}
}.start();
以下就是输出的日志
----Thread#main------mThreadLocal.get():main
----Thread#1------mThreadLocal.get():Thread#1
----Thread#2------mThreadLocal.get():Thread#2
从日志中可以看出(1)ThreadLocal中保存的都是每个线程中的局部变量,而且每个线程只能改变自己线程中的值.
ThreadLocal中部分方法的简介
- get() 获取当前线程保存的局部变量
- set() 设置当前线程的变量值
- remove() //移除当前变量的值
- setInitialValue() 私有的,设置初始化值
我们平时常用的也就get(),set()和remove()
public T get() {
Thread t = Thread.currentThread();
//获取当前线程中ThreadLocalMap变量,ThreadLocalMap是ThreadLocal中定义的类
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//如果map为空,就初始化map
return setInitialValue();
}
private T setInitialValue() {
T value = initialValue(); // 返回 null
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
二 ThreadLocal在Looper的作用
而我们在(Android消息机制Handler,Looper,Message,MessageQueue关系之一)提到过,base\core\java\android\os\Looper.java中出现了ThreadLocal
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
//主线程中获取Looper
public static Looper getMainLooper() {
synchronized (Looper.class) {
//在prepareMainLooper中初始化的
//因为一个应用只有一个主线,所以不用动态的获取
return sMainLooper;
}
}
public static void prepareMainLooper() {
prepare(false);//这里初始化并保存当前线程的Looper对象
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper(); //这里获取的主线程中的Looper
}
}
//最终都是调用sThreadLocal.get方法获取
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
ThreadLocal中存储的是Looper,而且每个线程中只能有一个Looper
所以我们可通过线程来获取当前线程中的Looper
历史上的今天
- 《2024: Android刷新媒体库的方法(0条评论)》
- 《2024: AudioTrack简单使用(1条评论)》
- 《2023: Android截图命令介绍(0条评论)》
- 《2022: 视频播放中,拖动进度条可以seek到相应视频帧(0条评论)》
- 《2021: Android应用启动时出现白屏或者黑屏问题的简介(0条评论)》
- 《2018: Looper中ThreadLocal的简介(0条评论)》
- 《2018: Android Studio快捷键记录(0条评论)》
- 《2018: Android消息机制之一基础简介(1)(0条评论)》
- 《2018: Google Nexus 7 adb devices时出现 ???????????? no permissions(0条评论)》
© 版权声明