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(...) 後に呼び出している(in Main)か、まったく呼び出していないdefineMain(...)(in teste(...))。スレッドを実行する前にmainを定義する必要があります。そうしないと、44行目に到達したときに次のようになる可能性myMainがあります。null

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が指摘したように、CoolThreadextendsの場合は、「」とThread言っnew CoolThread()てからcoolThread.start()。本当にあなたがすべきことは、を拡張する代わりにCoolThread実装することです。それはより良いパターンです:RunnableThread

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 が null であると思われます。Main クラスのコンストラクターで行うように、teste メソッド内から defineMain を呼び出す必要があります。

于 2012-08-20T22:56:55.887 に答える