我有一个工作线程坐在后台,处理消息。这样的东西:
class Worker extends Thread {
public volatile Handler handler; // actually private, of course
public void run() {
Looper.prepare();
mHandler = new Handler() { // the Handler hooks up to the current Thread
public boolean handleMessage(Message msg) {
// ...
}
};
Looper.loop();
}
}
从主线程(UI线程,不是那么重要)我想做这样的事情:
Worker worker = new Worker();
worker.start();
worker.handler.sendMessage(...);
麻烦的是,这让我为一个美丽的竞态条件:当时,worker.handler读取,没有办法确保工作线程已经分配到此字段!
我不能简单地从Worker的构造函数创建Handler,因为构造函数在主线程上运行,所以Handler将自己与错误的线程关联。
这似乎不是一个罕见的情况。我可以想出几个解决方法,他们都丑陋:
>这样的东西:
class Worker extends Thread {
public volatile Handler handler; // actually private, of course
public void run() {
Looper.prepare();
mHandler = new Handler() { // the Handler hooks up to the current Thread
public boolean handleMessage(Message msg) {
// ...
}
};
notifyAll(); //
Looper.loop();
}
}
并从主线程:
Worker worker = new Worker();
worker.start();
worker.wait(); //
worker.handler.sendMessage(...);
但是这也不可靠:如果notifyAll()发生在wait()之前,那么我们永远不会被唤醒!
>将初始消息传递给Worker的构造函数,并使用run()方法。一个ad-hoc解决方案,不适用于多个消息,或者如果我们不想立即发送,但很快之后。
>忙等待,直到处理程序字段不再为空。是的,最后的手段…
我想代表Worker线程创建一个Handler和MessageQueue,但这似乎是不可能的。什么是最优雅的方式呢?