2014-05-24 62 views
0

我有2個類(1是基本類,第二個擴展了Thread類),我試圖訪問一個對象(類),該對象在我的線程類中初始化setText()從另一個線程訪問一個對象

public class TThread extends Thread{ 

     Patcher pf; 

     public TThread(String string) { 
      setName(string); 
      start(); 
     } 

     @Override 
     public void run() { 
      pf = new Patcher("Checking Serial key..."); //<=== Class initialized here in a separate thread 
     } 

     public void setText(String string) { 
      pf.setText(string); //<=== Trying to access patcher here, throws NullPointerException 
     } 
} 

這是我怎麼稱呼TThread

public void myCall(){ 
    TThread tpf = new TThread("pf thread"); 
    //some code later 
    try{ 
     tpf.setText("blabla"); 
    } 

pf.setText()拋出NullPointerException當我試圖從另一個線程訪問補丁。

如何才能到達該線程並從另一個班級或此班級訪問修補程序?

+0

在'run'方法中只有構造函數是非常不尋常的,你確定在調用'yourTThreadObject.start()'之後調用'setText()'*嗎? – kajacx

+0

@kajacx我確定我沒有在'start()'之前調用'setText()'。我在一個類中初始化我的線程類,然後在10行後調用'setText()'。 –

回答

1

啓動新線程是一個耗時的過程。如果延遲很小,代碼將成功執行:

TThread thread = new TThread(「str」);

Thread.sleep(1000);

thread.setText(「str2」);

所以問題是你的線程沒有時間執行run方法(並創建實例)。你應該檢查實例的存在,並等待在setText方法中創建 - 或者在TThread的構造函數中實例化它。

4

這是經典的競賽條件。因爲你有兩個線程,所以不能保證首先會發生什麼。主線程在被後臺線程初始化之前可能會訪問pf

現在,你的程序是不可預知的。嘗試在setText方法的開頭添加Thread.sleep(100);。它似乎可以正常工作,但在某些特定情況下它可能仍會失敗。

一個解決它的方法是在主線程等待,直到pf初始化:

@Override 
public synchronized void run() { 
    pf = new Patcher("Checking Serial key..."); 
    notifyAll(); 
} 

public synchronized void setText(String string) throws InterruptedException { 
    while(pf==null) { 
     wait(); 
    } 
    pf.setText(string); 
} 

要小心。如果你之前沒有和線程一起工作,那麼正確的做法可能會非常棘手。