ThreadLocal

总结

默认成员变量是共享的

  • 简单说 ThreadLocal 就是一种以空间换时间的做法,在每个 Thread 里面维护了一个 ThreadLocalMap,而这个 map 的 key 就是 Threadlocal,值就是我们 set 的那个值,每次线程在 get 的时候,都从自己的变量中取值,既然从自己的变量中取值,所以不会影响其他线程。在这个线程是独享的,也没有线程安全方面的问题。
  • 通过它可以在指定的线程里存储数据,数据存储以后,只有在指定的线程中可以获取存储的数据,对于其他线程说则无法获取到数据。
  • 简单说 ThreadLocal 就是一种以空间换时间的做法,在每个 Thread 里面维护了一个以开地址法实现的 ThreadLocal. ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了
  • Map 和 Thread 绑定,所以虽然访问的是同一个 ThreadLocal 对象,但是访问的 Map 却不是同一个,所以取得值也不一样。
  • 可以看到, 先是获取当前线程对象, 然后从当前线程中获取线程的 Thread LocalMap, 值是添加到这个 ThreadLocalMap 中的, key 就是当前 Threadlocal 的对象。从使用的 AP 看上去像是把值存储在了 Threadlocal 中, 其实值是存储在线程内部, 然后关联了对应的 ThreadLocal, 这样通过 ThreadLocal. get 时就能获取到对应的值。
  • 很明显这种做法更科学,这也就是 ThreadLocal 的做法,因为铅笔(数据)本身就是同学(thread)自己在用,所以一开始就把铅笔交给同学自己保管是最好的,每个同学之间进行隔离。

说明一

unknown_filename.3|800

说明二

unknown_filename.4|800

在 Android 中的应用

  • messengeQueue-Looper 模型中,我们平常直接在 UI 线程中 new Handler ()就可以了,里面就是 mainLooper,但是 Android 怎么确定的 UIx 线程中 new Handler ()里面是 mainLooper 呢,答案就是通过将 Looper 作为 ThreadLocal 变量。
  • Choreographer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public final class Choreographer {  
private static final ThreadLocal<Choreographer> sThreadInstance =
new ThreadLocal<Choreographer>() {
@Override
protected Choreographer initialValue() {
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException("The current thread must have a looper!");
}
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};

private static volatile Choreographer mMainInstance;

}

Choreographer 主要是主线程用的,用于配合 VSYNC 中断信号。
所以这里使用 ThreadLocal 更多的意义在于完成线程单例的功能。

手写 ThreadLocal

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CustomThreadLoacl<T> {
// 存放变量副本的map容器,以 Thread 为 key,变量副本为 value
private Map<Thread, T> theadMap = new HashMap<Thread, T>();

public syncorhized T get() {
return theadMap.get(Thread.currentThread());
}

public synchroized set(T t) {
theadMap.set(Thread.currentThread(), t);
}
}

引用

【源码篇】ThreadLocal的奇思妙想(万字图文) - 掘金

理解Java中的ThreadLocal - 技术小黑屋


ThreadLocal
http://peiniwan.github.io/2024/04/2331ad96d5fa.html
作者
六月的雨
发布于
2024年4月6日
许可协议