-1

次のプログラムの出力で混乱しています

public class ChicksYack implements Runnable {
  Chicks c ;
  public static void main(String[] args){
    new ChicksYack().go();
  }

  void go(){
    c= new Chicks();
    new Thread(new ChicksYack()).start();
    new Thread(new ChicksYack()).start();
  }

  public void run() {
    c.yack(Thread.currentThread().getId());
  }
}

class Chicks{
  synchronized void yack(long id){
    for(int x = 1 ; x < 3 ; x++){
      System.out.print(id + " ");
      Thread.yield();
    }
  }
}

NullPointerExceptionプログラムは実行時にスローします。Chicks 変数 c の値は、スレッド 1 とスレッド 2 スタックで共有されませんか。私はかなりばかげた間違いを犯していることを知っていますが、かなり混乱しています。どんなポインタも役に立ちます。

4

3 に答える 3

3

Chicksの各インスタンスにのインスタンスがあることを確認する場合はChicksYack、次の行を移動する必要があります。

c= new Chicks();

コンストラクターに

public ChicksYack() {
    c= new Chicks();
}

メンバー変数の型を から に変更Chicks cfinal Chicks cます。そうしないと、スレッドで完全に構築されていることが保証されません。キーワードを追加すると、次のfinalことが保証されます。

コンストラクターが終了すると、最終フィールドの値は、構築されたオブジェクトにアクセスする他のスレッドから見えることが保証されます。(参照: Javamex.com Web サイト)

そのままで、メンバーが初期化ChicksYackされていないのインスタンスをさらに 2 つ作成しています。c

Chicksのすべてのインスタンス間で共有される のインスタンスを 1 つだけ持つ場合は、次のように宣言ChicksYackする必要があります。static

static Chicks c;
于 2013-08-11T18:39:57.140 に答える
1

ChicksYack の 3 つのインスタンスと Chicks の非静的フィールドがあります。

go メソッドをこのようなものに変更する必要があると思います

void go(){
  c= new Chicks();
  new Thread(this).start();
  new Thread(this).start();
}
于 2013-08-11T18:50:56.827 に答える
0

プログラムは、実行時に NullPointerException をスローします。Chicks 変数 c の値は、スレッド 1 とスレッド 2 スタックで共有されませんか。

コンピューターでは、実際にすぐに起こることは何もありません。何かがすぐにできると信じていたなら、それは忘れてください。つまり、スレッドはフィールドを更新できますが、他のスレッドから見えるようになるまでには時間がかかります。

いくつかの例外があり、1 つはvolatileフィールドを使用する場合 (更新を待機する代わりにインスタントではありません)、もう 1 つはスレッドが開始される前に設定された任意のフィールドです。このプログラムが実際に NPE をスローする場合、JVM にバグがあると思われます。私はあなたが最新バージョンを持っていることを確認します

于 2013-08-11T18:40:07.460 に答える