我有一些像这样的代码:
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();
}
}
我想知道“mHandler”属于哪个主题?
添加:如果我在不同的线程中声明(或实例化)它是不同的。
答案 0 :(得分:4)
它不属于任何主题。它是公共的,因此任何线程都可以访问它并进行修改。这就是说使线程安全至关重要(你的代码不是 - 变量不是volatile
)。
底线是 - 使用new
运算符创建的每个对象都放在所有线程之间共享的堆上。其他线程可以访问对象引用,例如如果它没有像你的例子中那样被封装或者是故意暴露的。
从技术上讲 - 在Java中,任何对象都不属于任何其他对象 - 对给定对象的所有引用都是相同的。当对象的最后一次引用(过度简化)消失时,就会收集垃圾。所以可以说:最后一个引用拥有对象。
答案 1 :(得分:1)
线程可以访问所有字段。只有局部变量存在于一个线程中。
如果要访问out块中的线程,可以使用。 LooperThread.this
答案 2 :(得分:0)
因为Handler
是一个内部类,所以它可以使用以下语法访问外部类:
public void handleMessage(Message msg) {
// process incoming messages here
Thread t = LooperThread.this;
}
从那里你应该知道该怎么做。
请注意:Thread
的实例是一个对象。但执行代码的线程是另一回事。不要将表示者Thread
与实际事物(CPU资源)混淆。
答案 3 :(得分:0)
尝试在handleMessage方法中使用它
Thread.currentThread().getName()
答案 4 :(得分:0)
如果您要问的是“从哪个线程可以安全地访问/修改变量mHandle
?”,那么,您的代码不会对分配进行任何锁定
mhandle = ...
因此从looper线程访问它是安全的。所以,如果你在另一个线程上检查了另一段代码
if (looperThread.mhandle == null) {
}
这不是线程安全的。您必须锁定作业和访问权限
synchronized (this) {
mhandle = ...
}
....
synchronized (looperThread) {
if (looperThread.mHandle == null) {
}
}
另一方面,如果您询问正在调用哪个线程handleMessage
,则从代码结构中看出它在looper线程上被调用 - 它看起来像{{1} }进入循环,等待消息,然后在消息到达时调用Looper.loop()
。不过只是一个猜测。
请记住,变量实际上并不属于某个线程 - 可以从任何线程访问它。真正的问题是,何时从哪些线程访问它是安全的?