小笔记:Handle
//这是Looper类中举例的一个用法。
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
前段时间面试了一家公司,问到Handle的时候,面试官问到了同一个线程为何不允许创建多个Looper,又是怎么做到的时候,我愣了,于是现在自己捋一下这个过程。
然后来说说自己的理解。
Looper在类内维护了一个静态ThreadLocal,(这里简要的说一下ThreadLocal的作用,就是当你所存储的对象需要和当前线程绑定时使用),这样在每个线程取出的Looper就能保证是当前的线程对应的Looper啦。
public class ThreadLocal<T> {
/**
* ThreadLocals rely on per-thread linear-probe hash maps attached
* to each thread (Thread.threadLocals and
* inheritableThreadLocals). The ThreadLocal objects act as keys,
* searched via threadLocalHashCode. This is a custom hash code
* (useful only within ThreadLocalMaps) that eliminates collisions
* in the common case where consecutively constructed ThreadLocals
* are used by the same threads, while remaining well-behaved in
* less common cases.
*/
private final int threadLocalHashCode = nextHashCode();
}
/**
* The next hash code to be given out. Updated atomically. Starts at
* zero.
*/
private static AtomicInteger nextHashCode =
new AtomicInteger();
/**
* Returns the next hash code.
*/
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
...
}
public
class Thread implements Runnable {
...
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
...
}
PS:
1、这里在提一下每一个Thread都会有一个自己的ThreadLocalMap。所以在通过ThreadLocal取值时,就能在自己线程的ThreadLocalMap去获取,保证了每个线程的数据不会互相污染。
2、终于能改名字了,不再是"qq_xxxxxx"了,哈哈,逃