Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程-为什么在运行时引发异常?_Java_Multithreading - Fatal编程技术网

Java 线程-为什么在运行时引发异常?

Java 线程-为什么在运行时引发异常?,java,multithreading,Java,Multithreading,我对以下程序的输出感到困惑 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 ChicksYa

我对以下程序的输出感到困惑

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实例中都有一个Chicks实例,则需要移动该行:

c= new Chicks();
进入构造器,例如

public ChicksYack() {
    c= new Chicks();
}
将成员变量的类型从Chicks c更改为final Chicks c;否则,不能保证在线程中看到它的完整构造。添加最终键盘可确保:

当构造函数退出时,最终字段的值保证对访问构造对象的其他线程可见。参考:网站

现在,您正在创建另外两个没有初始化c成员的ChicksYack实例

现在,如果您打算在所有ChicksYack实例中只共享一个Chicks实例,那么您需要将其声明为静态的,例如

程序在运行时抛出NullPointerException。Chicks变量c的值不会在线程1和线程2堆栈上共享

计算机中没有什么事情会立即发生。如果你相信任何事情都是瞬间发生的,那就忘掉它吧。这意味着,虽然一个线程可以更新一个字段,但其他线程需要时间才能看到它


有许多例外,一个是使用易失性字段,它仍然不是即时的,而是等待任何更新,另一个是在线程启动之前设置的任何字段。如果这个程序真的为您抛出了一个NPE,我会怀疑您的JVM中有一个bug。我会确保您拥有最新版本

您有三个ChicksYack实例,而不是Chicks的静态字段

我想你应该把围棋的方法改成这样

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

暗中拍摄:在代码清单的第二行初始化Chick c?此外,stacktrace也会有所帮助。实例之间不共享c。在main中创建一个实例,在go中设置该实例的c,然后创建两个新实例,它们的c+0中有空值。这是一个好主意,该字段必须是final,以确保可以看到它。“只是移动它不会有任何区别。”皮特,我意识到了这个问题。这是一个相当愚蠢的问题。谢谢你的澄清。
void go(){
  c= new Chicks();
  new Thread(this).start();
  new Thread(this).start();
}