ThreadLocal如何保证一个线程只能有一个Looper?

我们都知道在调用Looper.prepare的时候会创建一个Looper,那么是如何保证一个线程只有一个Looper的?

首先要知道Looper中有一个sThreadLocal变量,ThreadLocal用于存储上下文信息

并且用final static 修饰,所以它是唯一的内容不可变的

了解sThreadLocal是干啥用的后,再来看看prepare

先调用sThreadLocal.get()方法

而ThreadLocalMap 是一个HashMap,那么取到一个HashMap后判断是否为null

如果不存在key为sThreadLocal的节点,得到value = null,并把这个value作为sThreadLocal的值即<sThreadLocal,null>;如果map为null,则创建一个HashMap并把<sThreadLocal,null>节点加入

这样get方法就要么取到一个Looper,要么就是null,如果为Looper则抛异常,如果为null,则调用sThreadLocal.set()

其实都是把Looper作为sThreadLocal的value值

回到开头说的,怎么保证一个线程只有一个Looper?

因为sThreadLocal是线程的上下文,并且唯一,而线程中存有<sThreadLocal,Looper>key-value键值对,所以一个sThreadLocal对应一个Looper,并且再次修改Looper是,会抛异常,因为Looper已经存在。

所以一个线程只有一个Looper。

如果对HashMap还不了解的同学,这篇文章可能对你有一定帮助 HashMap原理