2014-05-24 60 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); 
} 

要小心。如果你之前没有和线程一起工作,那么正确的做法可能会非常棘手。