ThreadLocal是线程内部数据存储类,通过它可以在指定线程中存储数据,且只能在该线程中访问,如在调用栈比较深时用于存储监听器,不需要全局变量即可实现监听线程的全部执行过程,且避免了监听器通过参数去传递
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private ThreadLocal mBooleanThreadLocal = new ThreadLocal<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBooleanThreadLocal.set(true);
Log.d(TAG, "onCreate: Thread#main mBooleanThreadLocal = " + mBooleanThreadLocal.get());
new Thread("Thread#1"){
@Override
public void run() {
mBooleanThreadLocal.set(false);
Log.d(TAG, "onCreate: Thread#1 mBooleanThreadLocal = " + mBooleanThreadLocal.get());
}
}.start();
new Thread("Thread#2"){
@Override
public void run() {
Log.d(TAG, "onCreate: Thread#2 mBooleanThreadLocal = " + mBooleanThreadLocal.get());
}
}.start();
}
}
打印如下,虽然不同线程使用同一个ThreadLocal对象,但值却不一样
Thread#main mBooleanThreadLocal = true
Thread#1 mBooleanThreadLocal = false
Thread#2 mBooleanThreadLocal = null
其set()方法如下,内部通过所传入线程threadLocals(ThreadLocalMap.Entry)存储数据
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
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);
}
static class Entry extends WeakReference> {
Object value;
Entry(ThreadLocal> k, Object v) {
super(k);
value = v;
}
}
再看下set()的实际实现
private void set(ThreadLocal> key, Object value) {
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1);
for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal> k = e.get();
if (k == key) {
e.value = value;
return;
}
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
其get()方法如下,若存在则返回数据,不存在则创建ThreadLocalMap,存储默认值null并返回
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
protected T initialValue() {
return null;
}
如下为插入操作enqueueMessage(),主要为链表的插入
boolean enqueueMessage(Message msg, long when) {
......
synchronized (this) {
......
msg.markInUse();
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p;
prev.next = msg;
}
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
如下为读取操作,死循环遍历链表,在规定时间后将Message返回并从链表删除
Message next() {
......
for (; ; ) {
......
synchronized (this) {
final long now = SystemClock.uptimeMillis();
Message prevMsg = null;
Message msg = mMessages;
if (msg != null && msg.target == null) {
do {
prevMsg = msg;
msg = msg.next;
} while (msg != null && !msg.isAsynchronous());
}
if (msg != null) {
if (now < msg.when) {
nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
} else {
mBlocked = false;
if (prevMsg != null) {
prevMsg.next = msg.next;
} else {
mMessages = msg.next;
}
msg.next = null;
msg.markInUse();
return msg;
}
}
......
}
......
}
}
使用Handler需要Looper,否则会报错
可修改为如下
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread("Thread#1") {
@Override
public void run() {
Looper.prepare();
Looper looper = Looper.myLooper();
Handler handler = new Handler();
Looper.loop();
}
}.start();
}
}
prepare()创建Looper(内部创建MessageQueue),并存储到ThreadLocal
public static void prepare() {
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
loop()开启消息循环
public static void loop() {
final Looper me = myLooper();
......
final MessageQueue queue = me.mQueue;
for (;;) {
Message msg = queue.next();
if (msg == null) {
return;
}
......
try {
msg.target.dispatchMessage(msg);
......
}
......
}
}
sendMessage()将Message插入到MessageQueue
public final boolean sendMessage(@NonNull Message msg) {
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
long uptimeMillis) {
msg.target = this;
msg.workSourceUid = ThreadLocalWorkSource.getUid();
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
dispatchMessage()方法
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
Activity中的runOnUiThread(),若当前线程是主线程,则直接执行,否则调用主线程创建的Handler中的post()
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}