变量属于哪个线程?

时间:2011-10-09 13:03:06

标签: java multithreading variables

我有一些像这样的代码:

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”属于哪个主题?

添加:如果我在不同的线程中声明(或实例化)它是不同的。

5 个答案:

答案 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()。不过只是一个猜测。

请记住,变量实际上并不属于某个线程 - 可以从任何线程访问它。真正的问题是,何时从哪些线程访问它是安全的?