昨天写的程序有点差强人意,既然是这个机制是多线程操作的,就要多用用线程的概念。
准备知识:
1. obj.notify() 与 obj.wait()
分别表示:
释放等待队列中等待在obj对象上的线程;
当前线程因需要等待obj对象而进入等待队列
2. ThreadLocal类,知道其get()与set(obj)方法的含义。
参考源码jdk1.5:
总体思路:
每个线程都有一个ThreadLocalMap。
当调用ThreadLocal.set(value)时,取出当前线程的ThreadLocalMap,然后map.set(ThreadLocal对象,value);
当调用ThreadLocal.get()时,取出当前线程的ThreadLocalMap,然后return map.get(ThreadLocal对象);
源码:
public class ThreadLocal
private final int threadLocalHashCode = nextHashCode();
private static int nextHashCode = 0;
private static final int HASH_INCREMENT = 0x61c88647;
private static synchronized int nextHashCode() {
int h = nextHashCode;
nextHashCode = h + HASH_INCREMENT;
return h;
}
public ThreadLocal() {
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
return (T)map.get(this);
// Maps are constructed lazily. if the map for this thread
// doesn't exist, create it, with this ThreadLocal and its
// initial value as its only entry.
T value = initialValue();
createMap(t, value);
return value;
}
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);
}
.......
static class ThreadLocalMap {
........
}
}
最后看看改进的ThreadHandler和Looper类
package com.zte.liu;
public class HandlerThread extends Thread{
private Looper mLooper;
public void run(){
Looper.prepare();
synchronized(this){//本身线程会对mLooper存储区域做写操作,故需要放置临界区
mLooper = Looper.myLooper();
this.notifyAll();//通知等待在this对象上的线程走出等待队列
}
Looper.loop();
}
public Looper getLooper(){//其他线程会对mLooper存储区域做读操作,故需要放置临界区
if(!isAlive()){
return null;
}
//if the thread has been started, wait until the looper has been created.
synchronized(this){
while(isAlive() && mLooper==null){
try {
this.wait();//当前线程因等待this对象而进入等待队列
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return mLooper;
}
}
package com.zte.liu;
import com.zte.liu.*;
public class Looper{
private static final ThreadLocal sThreadLocal = new ThreadLocal();
private MessageQueue
private Looper(){
mQueue = new MessageQueue
}
public synchronized static final void prepare(){
if(sThreadLocal.get() != null){
throw new RuntimeException("sThreadLocal already contains looper object");
}
sThreadLocal.set(new Looper());
}
public static final void loop(){
System.out.println("loop begin...");
Looper looper = myLooper();
MessageQueue
if(looper == null) {
return;
}
while(true){
System.out.println("----queue size ="+queue.size());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg = (Message)queue.next();
if(msg != null){
if(msg.getHandler() == null)return;
else{
msg.getHandler().dispatchMsg(msg);
Message.recycle(msg);
}
}
}
}
public static Looper myLooper(){
return (Looper)(sThreadLocal.get());
}
public MessageQueue
return mQueue;
}
}