-1

I am solving the below interview question. It's throwing a NullPointerException, but I do not understand how the value of c is null. I already initialized it in the go() method.

package swain.javainterviewhub.blogspot.in;

class Chicks{
    synchronized void yack(long id){
        for(int x=1;x<3;x++){
            System.out.println(id+" ");
            Thread.yield();
        }
    }
}

public class JavaInterviewHub implements Runnable {

    Chicks c;

    public static void main(String[] args) {
        new JavaInterviewHub().go();
    }

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

    @Override
    public void run() {
        c.yack(Thread.currentThread().getId());
    }

}

Console:

 Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.NullPointerException
        at swain.javainterviewhub.blogspot.in.JavaInterviewHub.run(JavaInterviewHub.java:28)
        at java.lang.Thread.run(Unknown Source)
    java.lang.NullPointerException
        at swain.javainterviewhub.blogspot.in.JavaInterviewHub.run(JavaInterviewHub.java:28)
        at java.lang.Thread.run(Unknown Source)
Sitansu
  • 3,225
  • 8
  • 34
  • 61
  • Each instance of JavaInterviewHub has its own c field? – user253751 Aug 29 '15 at 04:07
  • 1
    `new Thread(new JavaInterviewHub()).start();` - The `JavaInterviewHub` created here does not have its `c` field initialized. – resueman Aug 29 '15 at 04:09
  • @immibis can you please briefly explain what happening here – Sitansu Aug 29 '15 at 04:09
  • possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – akash Aug 29 '15 at 04:16

2 Answers2

4

Since Chicks.yack() is synchronized, you probably meant for both threads to use the same instance of Chicks, which means you probably meant for both threads to use the same instance of JavaInterviewHub, in which case you probably meant to start both threads with the instance that was created in main().

If that's all true, then you need to use this when creating the threads:

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

As for the question of when to create an instance of Chicks, and therefore assign a value to c, you have 3 choices:

  1. Leave the code as-is. A bit obscure, but valid.
  2. Do it in a constructor.
  3. Do it when declaring c. Easiest.

Option 2: Constructor

private JavaInterviewHub() {
    this.c = new Chicks();
}

Option 3: Declaration

private final Chicks c = new Chicks();
Andreas
  • 154,647
  • 11
  • 152
  • 247
1

When you create a thread like this:

new Thread(new JavaInterviewHub()).start();

A new instance of JavaInterviewHub is created. In this instance c is not set anywhere, so when the run method is executed, a NullPointerException is thrown.

One way to solve the issue is to initialize c in JavaInterviewHub's constructor. Another would be to initialize c where it's declared. See the acepted answer for more information.

Esteban Herrera
  • 2,263
  • 2
  • 23
  • 32
  • If you do that, then you have a total of 3 instances of both `JavaInterviewHub` and `Chicks`, and there's no need to *synchronize* `yack()`. – Andreas Aug 29 '15 at 04:25
  • The reason why the program creates multiple instances of `JavaInterviewHub` is not because it "creates new threads like this..." It's because of the `new JavaInterviewHub()`. I realize that's the bulk of the "like this" that you were talking about, but these newbies need a lot of hand-holding. Don't confuse 'em by saying "when you create a new thread" if creating the thread is not the problem. – Solomon Slow Aug 29 '15 at 16:38