- ThreadLocal分析
是一个线程内部存储类,数据存储后,只能通过指定的线程读取,其他线程无法获取。
set()、 get() 方法操作的都是当前线程ThreadLocalMap对象里面 的table数组。
/**
保存数据:set方法
**/
public void set(T value) {
Thread t = Thread.currentThread(); //获取当前线程
ThreadLocalMap map = getMap(t); //获取当前线程存储的数据
if (map != null) //当前线程数据存在,直接设置更新
map.set(this, value);
else //不存在,创建ThreadLocalMap 对象,并将数据保存
createMap(t, value);
}
/**
createMap方法
**/
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
/**
ThreadLocalMap构造方法
**/
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue); //数据存入
size = 1;
setThreshold(INITIAL_CAPACITY);
}
/**
数据获取: get()方法
**/
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this); //从ThreadLocalMap里面取出当前线程的数据
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue(); //不存在数据 设置初始化数据为null
}
/**
初始数据: setInitialValue()方法
**/
private T setInitialValue() {
T value = initialValue(); // initialValue 返回为null,直接将value设置为null
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
- MessageQueue
enqueueMessage() 方法: 往消息队列里插入一条消息
next() 方法:从消息队列里取出一条消息并将其从消息队列里移除
/**
往消息队列里插入一条消息: enqueueMessage()方法
**/
boolean enqueueMessage(Message msg, long when) {
if (msg.target == null) {
throw new IllegalArgumentException("Message must have a target.");
}
if (msg.isInUse()) {
throw new IllegalStateException(msg + " This message is already in use.");
}
synchronized (this) {
if (mQuitting) {
IllegalStateException e = new IllegalStateException(
msg.target + " sending message to a Handler on a dead thread");
Log.w(TAG, e.getMessage(), e);
msg.recycle();
return false;
}
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
needWak