2

Thread拡張するクラスをサブクラス化し、次のコードを記述してテストした場合、結果がどうなるか疑問に思っています。

class A extends Thread {
    public A() {
        this.start();
    }
    public void run() {
        System.out.println(" in A " + Thread.currentThread().getName());
    }
}

class B extends A {
    public void run() {
        System.out.println(" in B " + Thread.currentThread().getName());
    }
}

public class OverrideRun {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
    }    
}

結果は次のとおりです。

A スレッド 0
で B スレッド 1 で

しかし、なぜ2つのスレッドが作成されるのかわかりませんか?

4

5 に答える 5

3

これは、B b = new B();ステートメントが class の引数パラメーターをB呼び出しておらず、 class の引数パラメーター コンストラクター (デフォルト) を呼び出していないためAです。

これは、コンストラクターの連鎖によるものです。

于 2012-06-26T13:34:46.767 に答える
2

これは、次のように2 つのスレッド ( から継承された 2 つのオブジェクト) を作成したためですThread

public static void main(String[] args) {
    A a = new A(); // #1
    B b = new B(); // #2
}
于 2012-06-26T13:34:54.100 に答える
2

しかし、なぜ2つのスレッドが作成されるのかわかりませんか?

A()コンストラクターで開始しているため、2 つのスレッドが開始されます。

public A() {
    this.start();
}

そして、あなたは2つのオブジェクトを構築しています - anAと aBを拡張しますA:

    A a = new A();
    B b = new B();

デフォルトでは、new B()引数なしのコンストラクタがないので言うと、スーパークラスの引数なしのコンストラクタを呼び出します。したがってA、スレッドを開始するコンストラクターが呼び出されます。ここで Java のドキュメントを参照してください。引用するには:

クラスにコンストラクターを提供する必要はありませんが、これを行うときは注意が必要です。コンパイラーは、コンストラクターを持たないすべてのクラスに対して、引数のない既定のコンストラクターを自動的に提供します。このデフォルト コンストラクターは、スーパークラスの引数なしのコンストラクターを呼び出します。この状況では、スーパークラスに引数のないコンストラクターがない場合、コンパイラーはエラーを出すので、それを確認する必要があります。クラスに明示的なスーパークラスがない場合、引数のないコンストラクターを持つ Object の暗黙的なスーパークラスがあります。

余談ですが、コンストラクター内でスレッドを開始することはお勧めできません。これを行うと、いくつかのスレッド競合状態が発生する可能性があります。a.start()に電話してから電話する方がはるかに良いですnew A()Runnableまた、を拡張する代わりに実装するクラスを定義する方が良いパターンThreadです。したがって、コードは次のようになります。

class A implements Runnable() {
     public A() {
         // don't start it here
     }
     public void run() {
         ...
     }
}
...

Thread a = new Thread(new A());
a.start();
Thread b = new Thread(new B());
b.start();
于 2012-06-26T13:35:04.877 に答える
2

Aextends ThreadBextendsAであるため、 のインスタンスAと のインスタンスを作成すると、 のB2 つのインスタンスが作成されますThread

一般に、 extendsではなく、単に実装してからコンストラクターに渡す方が好ましいことに注意してください。これは、設計の観点からはよりクリーンになります。スレッドの動作を実際に変更しようとしているのではなく、実行する別のタスクを与えているだけです。ThreadRunnableRunnableThread(Runnable)

(一般的には、最初からスレッドを直接作成するよりも、java.util.concurrent の機能を使用する方が適切ですが、これで終わりです...)

于 2012-06-26T13:35:11.483 に答える
1

次の行を実行して要求しているため、2 つのスレッドが作成されています。

    A a = new A();
    B b = new B();
于 2012-06-26T13:36:08.403 に答える