我有一个位于后台的工作线程,处理消息。像这样的东西:
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
读取时,无法确定工作线程已经分配给这个字段!
我不能简单地Handler
从Worker
的构造函数中创建,因为构造函数在主线程上运行,所以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(); // <- ADDED Looper.loop(); } }
从主线程:
Worker worker = new Worker(); worker.start(); worker.wait(); // <- ADDED worker.handler.sendMessage(...);
但这也不可靠:如果
notifyAll()
发生在 之前wait()
,那么我们将永远不会被唤醒!将初始值传递
Message
给Worker
的构造函数,让run()
方法发布它。临时解决方案不适用于多条消息,或者如果我们不想立即发送,但很快就会发送。等到
handler
田野不再忙碌null
。是的,最后的手段...
我想创建一个Handler
和MessageQueue
代表Worker
线程,但这似乎是不可能的。最优雅的方法是什么?