线程无缘无故地给出NullPointerException

Yar*_*oze 1 java multithreading nullpointerexception

所以我正在做这个尴尬的例子来理解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();
    }

}
Run Code Online (Sandbox Code Playgroud)
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();
    }

}

}
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

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

Gra*_*ray 8

myThread.defineMain(...) 开始你的线程(in Main)或者根本没有调用defineMain(...)(in teste(...))之后调用.你需要在线程运行之前定义main,否则有可能myMainnull你到达第44行,我假设是:

myMain.teste("The sum is: " + soma);
Run Code Online (Sandbox Code Playgroud)

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

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();
Run Code Online (Sandbox Code Playgroud)

永远不要认为JDK是错误的.这将扼杀您用于查找问题的任何调试和批判性思维.学习如何在eclipse中使用调试器.然后,您可以在第44行放置一个断点并调查变量.

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


另外,正如@kurtzbot指出的那样,如果CoolThread延伸,Thread那么你可以说new CoolThread(),然后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() {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)