1

所以我正在做这个尴尬的例子来了解 Java 中的线程是如何工作的。实际上这很简单,但是,我似乎不明白为什么当它尝试触发超过 3 个线程时它会给我一个 NullPointerException 异常。

你能整理出来吗?Eclipse 的调试器没有帮助:-(

提前致谢!!

public class Main {

    public static void main(String[] args) {

        Main boot = new Main();
    }

    public Main()
    {
        CoolThread myThread = new CoolThread(1, 2);
        Thread t_myThread = new Thread(myThread);
        t_myThread.start();

        myThread.defineMain(this);
    }


    public void teste(String tests){
        CoolThread myThread = new CoolThread(1, 2);
        Thread t_myThread = new Thread(myThread);
        t_myThread.start();
    }

}

public class CoolThread extends Thread {

int firstNum;
int secondNum;
Main myMain;

/**
 * Constructor
 * @param firstNum
 * @param secondNum
 */
public CoolThread(int firstNum, int secondNum)
{
    this.firstNum = firstNum;
    this.secondNum = secondNum;
}

public void defineMain(Main myMain)
{
    this.myMain = myMain;
}
/**
 * Fires the thread.
 */
public void run()
{
    try{
        int number = 0;
        for(;;)
        {

            int soma = (firstNum+secondNum);
            System.out.println("ID: " +Thread.currentThread().getId());
            firstNum++;
            secondNum++;
            number++;
            Thread.sleep(100);
            if((number % 10) == 0)
            {
                myMain.teste("The sum is: " + soma);
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

}

}

顺便说一句,这是我得到的输出:

ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 9
ID: 12
ID: 9
ID: 12
ID: 12
ID: 9
ID: 12
ID: 9
ID: 12
ID: 9
ID: 12
ID: 9
ID: 12
ID: 9
ID: 12
ID: 9
ID: 12
ID: 9
ID: 9
ID: 12
ID: 9
ID: 14
java.lang.NullPointerException
    at my.own.package.CoolThread.run(CoolThread.java:44)
    at java.lang.Thread.run(Thread.java:722)

它继续创建和杀死线程......

4

2 回答 2

8

您要么在启动线程myThread.defineMain(...) Main调用(in ),要么根本不调用defineMain(...)(in teste(...))。您需要在线程运行之前定义 main ,否则有可能在您到达第 44 行时,我假设是myMainnull

myMain.teste("The sum is: " + soma);

这是线程竞争条件的定义。您的起始代码应为:

CoolThread myThread = new CoolThread(1, 2);
// this must be done _before_ the thread starts below
myThread.defineMain(this);
Thread t_myThread = new Thread(myThread);
t_myThread.start();

永远不要认为 JDK 是错误的。这只会扼杀你用来发现问题的任何调试和批判性思维。了解如何在 eclipse 中使用调试器。然后,您可以在第 44 行设置断点并调查变量。

不幸的是,在这种情况下,您有一个线程程序,并且调试正在改变程序的时间,并且很可能隐藏了错误。您可能尝试在第 44 行打印出各种对象,以查看哪个是null.


此外,正如@kurtzbot 指出的那样,如果CoolThreadextendsThread那么你可以说new CoolThread()then coolThread.start()。真正你应该做的是CoolThread实现Runnable而不是扩展Thread。这是更好的模式:

CoolThread myThread = new CoolThread(1, 2);
// this must be done _before_ the thread starts below
myThread.defineMain(this);
Thread t_myThread = new Thread(myThread);
t_myThread.start();
...

public class CoolThread implements Runnable {
    public void run() {
        ...
    }
}
于 2012-08-20T22:51:59.073 回答
0

当从 teste 方法启动新线程时,我怀疑 myMain 为空。您需要从 teste 方法中调用 defineMain ,就像在 Main 类的构造函数中一样。

于 2012-08-20T22:56:55.887 回答