多线程实例字段实现

0 java multithreading scjp ocpjp

public class Chicks {
    synchronized void yacks(long id)
    {
        for(int x = 1; x<3; x++)
        {
            System.out.println(id + " ");
            Thread.yield();
        }
    }
}
class ChickYacks implements Runnable
{
    Chicks c; // No exception if I declare it as static
    public static void main(String[] args) {
        new ChickYacks().go();
    }
    public void run()
    {
        c.yacks(Thread.currentThread().getId()); //Throws a Nullpointer exceptin
    }
    void go()
    {
        c = new Chicks();
        new Thread(new ChickYacks()).start();
        new Thread(new ChickYacks()).start();
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么它会抛出一个Nullpointer异常run method().一切看起来都很好.当我宣布Chicks 'c'为静态但我不理解为什么?

Jon*_*eet 6

您的go方法为"this"实例分配了一个非null值ChickYacks- 但随后创建了两个实例ChickYacks,每个实例都有一个null值c.

你可以:

  • c而是在构造函数中初始化,以便每个实例都具有非null值
  • 初始化c一个字段初始
  • crun()方法中初始化
  • 初始化c的实例go方法
  • 传递thisThread构造函数而不是创建新实例
  • 使c静态变为无关紧要从哪个实例访问它(或者实际上是否用静态方法访问它;它将与类型相关联而不是与实例相关联)

这与线程无关,真的.如果你没有使用线程,你会得到同样的效果,只是在原始线程中抛出异常而不是新线程:

void go()
{
    c = new Chicks();
    new ChickYacks().run(); // Bang!
    new ChickYacks().run();
}
Run Code Online (Sandbox Code Playgroud)

  • @kvp:不,因为你在错误的实例中初始化它.你了解实例字段的工作原理吗?创建新实例时,该实例具有一组单独的字段... (2认同)