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();
}