簡體   English   中英

線程-為什么在運行時引發異常?

[英]Threads - why exception is thrown at runtime?

我對以下程序的輸出感到困惑

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堆棧上共享。 我知道我犯了一個非常愚蠢的錯誤,但是卻很困惑。 任何指針都會有所幫助。

如果要確保在ChicksYack每個實例中ChicksYack一個Chicks實例,則需要移動以下行:

c= new Chicks();

進入構造函數

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

並將成員變量的類型從Chicks c更改為final Chicks c ; 否則,您將無法保證將在線程中完全構建它。 添加final密鑰集可確保:

構造函數退出時 ,可以確保 final字段的值對訪問構造對象的其他線程可見 (參考: Javamex.com網站)

ChicksYack ,您ChicksYack創建兩個未初始化c成員的ChicksYack實例。

現在,如果您打算在ChicksYack所有實例中ChicksYack共享一個Chicks實例,則需要將其聲明為static實例,例如

static Chicks c;

您有ChicksYack的三個實例和Chicks的非靜態字段。

我認為您應該將go方法更改為這樣的內容

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

該程序在運行時引發NullPointerException。 Chicks變量c的值是否不會在線程1和線程2堆棧上共享。

計算機上沒有任何事情會立即發生。 如果您認為任何事情都是即時的,那就算了。 這意味着盡管一個線程可以更新字段,但要花費時間才能讓其他線程看到。

有很多例外,一個例外是使用volatile字段(它仍然不是即時的,而是等待任何更新),另一個例外是在啟動線程之前設置的任何字段。 如果該程序確實為您拋出了NPE,我會懷疑您的JVM中存在錯誤。 我會確保您擁有最新版本

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM