2011-10-09 58 views
0

我哈瓦像這樣的代碼:變量屬於哪個線程?

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」屬於哪一種?

添加:如果我在不同的線程中聲明(或實例化)它是不同的。

+3

你的問題沒有意義。 mHanlder只是被定義的。它尚未在任何線程中使用。一個對象不屬於某個線程。 – home

+0

'Looper'類在您的代碼片段中無關緊要,爲清晰起見,請將其刪除。 –

+0

是你的問題,從哪個線程安全地修改/訪問mHandler變量?或者你問你在哪個線程調用'handleMessage'? – Owen

回答

4

內它不屬於任何線程。它是公開的,所以任何線程都可以訪問它並進行修改。話雖如此,讓它線程安全是至關重要的(你的代碼不是 - 變量不是volatile)。

底線是 - 使用new運算符創建的每個對象都放置在所有線程共享的堆上。其他線程可以訪問對象引用,例如如果它沒有像你的例子那樣封裝或者是故意暴露的話。

從技術上說 - 在Java中任何對象都不屬於任何其他對象 - 對給定對象的所有引用都是相同的。當對象的最後一個引用(巨大的過分簡化)消失時,它就會被垃圾收集。所以可以這樣說:最後的參考擁有的對象。

+0

如果我在不同的線程中聲明(或實例化)它有什麼不同? – HiMing

+1

不,從Java/JVM的角度來看,創建對象的線程並不重要。一旦它被初始化並且構造函數被執行,那麼任何可以訪問它的線程都可以平等地使用該對象的引用。 –

0

因爲Handler是一個內部類,它可以使用此語法訪問外部類:

 public void handleMessage(Message msg) { 
      // process incoming messages here 
      Thread t = LooperThread.this; 
     } 

從那裏,你應該知道怎麼做。

請注意:Thread的實例是一個對象。但是其中執行代碼的線程完全是另一回事。不要將代表Thread與實際事物(CPU資源)混淆。

0

嘗試使用此您的handleMessage方法

Thread.currentThread().getName() 
1

線程可以訪問所有字段。只有局部變量只存在於一個線程中。

如果您想訪問out塊中的線程,您可以使用。 LooperThread.this

0

如果你所要求的是「從哪些線程是安全的訪問/修改變量mHandle?」,現在,你的代碼沒有任何鎖定的分配各地

mhandle = ... 

所以只有從彎針線上才能安全進入。所以如果你在另一個線程上有另一個代碼檢查

if (looperThread.mhandle == null) { 
} 

這將不是線程安全的。你不得不鎖定兩個左右的分配和訪問

synchronized (this) { 
    mhandle = ... 
} 
.... 
synchronized (looperThread) { 
    if (looperThread.mHandle == null) { 
    } 
} 

在另一方面,如果你問哪個線程handleMessage被調用時,它似乎從它被調用的代碼結構在循環線程上 - 它看起來像Looper.loop()進入循環,等待消息,然後在消息到達時調用handleMessage()。只是猜測,但。

只要記住一個變量實際上不屬於一個線程 - 它可以從任何線程訪問。真正的問題是,什麼時候可以安全地從哪個線程訪問它?