Java 多线程实例字段实现 公共类小鸡{ 同步的无效yacks(长id) { 对于(int x=1;x

Java 多线程实例字段实现 公共类小鸡{ 同步的无效yacks(长id) { 对于(int x=1;x,java,multithreading,scjp,ocpjp,Java,Multithreading,Scjp,Ocpjp,您的go方法为ChickYacks的“this”实例指定一个非空值,但随后创建两个ChickYacks的新实例,每个实例的c都有一个空值 你可以: 在构造函数中初始化c,这样每个实例都有一个非空值 在字段初始值设定项中初始化c 在run()方法中初始化c 在go方法中为新实例初始化c 将此传递给线程构造函数,而不是创建新实例 将c设为静态,这样无论您从哪个实例访问它(或者实际上是否使用静态方法访问它;它将与类型关联,而不是与实例关联) 这与线程无关。如果不使用线程,也会得到同样的效果,只是在

您的
go
方法为
ChickYacks
的“this”实例指定一个非空值,但随后创建两个
ChickYacks
的新实例,每个实例的
c
都有一个空值

你可以:

  • 在构造函数中初始化
    c
    ,这样每个实例都有一个非空值
  • 在字段初始值设定项中初始化
    c
  • run()
    方法中初始化
    c
  • go
    方法中为新实例初始化
    c
  • 传递给
    线程
    构造函数,而不是创建新实例
  • c
    设为静态,这样无论您从哪个实例访问它(或者实际上是否使用静态方法访问它;它将与类型关联,而不是与实例关联)
这与线程无关。如果不使用线程,也会得到同样的效果,只是在原始线程而不是新线程中抛出异常:

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

您的
go
方法为
ChickYacks
的“this”实例指定一个非空值,但随后创建两个
ChickYacks
的新实例,每个实例的
c
都有一个空值

你可以:

  • 在构造函数中初始化
    c
    ,这样每个实例都有一个非空值
  • 在字段初始值设定项中初始化
    c
  • run()
    方法中初始化
    c
  • go
    方法中为新实例初始化
    c
  • 传递给
    线程
    构造函数,而不是创建新实例
  • c
    设为静态,这样无论您从哪个实例访问它(或者实际上是否使用静态方法访问它;它将与类型关联,而不是与实例关联)
这与线程无关。如果不使用线程,也会得到同样的效果,只是在原始线程而不是新线程中抛出异常:

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

请注意,这与多线程无关。您只是在创建对象,忘记为这些对象的字段分配非空值,然后在此空字段上调用方法。请注意,这与多线程无关。您只是在创建对象,忘记为这些对象的字段分配非空值d然后在这个空字段上调用一个方法。哇!John Skeet回答了我的问题。它一定是100%正确:)此外,我喜欢你回答了我的问题,但我仍然不明白:/“非空值到”这个“Chickyaks实例”-它的意思是什么?@kvp:你不明白哪一位?我已经扩展了我的答案。(第二次-不可靠的网络连接破坏了第一次扩展…)在这种情况下初始化它意味着
Chicks c=new Chicks()
对吗?就因为
c'对象为null,它就抛出了
NullPointerException`?@kvp:不,因为您在错误的实例中初始化了它。您了解实例字段是如何工作的吗?当您创建一个新实例时,它有一组单独的字段…哇!John Skeet回答了我的问题。它必须是100%正确的:)此外,我喜欢你回答了我的问题,但我仍然不明白:/“非空值到”这个“ChickYacks实例”-这是什么意思?@kvp:你不明白哪一点?我已经扩展了我的答案。(第二次-不可靠的网络连接吃掉了第一次扩展…)在本例中初始化它意味着
Chicks c=new Chicks();
对吗?所以仅仅因为
c'对象为null,它就抛出了
NullPointerException`?@kvp:不,因为您在错误的实例中初始化了它。您了解实例字段是如何工作的吗?当您创建一个新实例时,它有一组单独的字段。。。