2015-08-29 3 views
-1

Я решаю вопрос ниже. Это бросает NullPointerException, но я не понимаю, как значение c равно null. Я уже инициализировал его в методе go().Почему объект c null в методе запуска?

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

} 

консоли:

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) 
+0

Каждый экземпляр JavaInterviewHub имеет свое собственное поле гр? – immibis

+1

'new Thread (новый JavaInterviewHub()). Start();' - Созданный здесь '' JavaInterviewHub '' не имеет своего поля 'c', инициализированного. – resueman

+0

@immibis вы можете вкратце объяснить, что здесь происходит – Sitansu

ответ

4

С Chicks.yack() является synchronized, вы, вероятно, означало для начала обе нити с обеих нитей, чтобы использовать один и тот же экземпляр Chicks, что означает, что вы, вероятно, означало для обеих нитей, чтобы использовать один и тот же экземпляр JavaInterviewHub, в этом случае вы, вероятно, означало экземпляр, созданный в main().

Если все это правда, то вам нужно использовать this при создании темы:

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

Что касается вопроса о том, когда для создания экземпляра Chicks, и поэтому присвоить значение c , у вас есть 3 варианта:

  1. Оставьте код как есть. Немного неясна, но действует.
  2. Сделайте это в конструкторе.
  3. Сделайте это, объявив c. Самый простой.

Вариант 2: Конструктор

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

Вариант 3: Декларация

private final Chicks c = new Chicks(); 
1

При создании нить вроде этого:

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

Новый экземпляр JavaInterviewHub создается. В этом случае c не установлен нигде, поэтому, когда выполняется метод run, бросается NullPointerException.

Одним из способов решения проблемы является инициализация c в конструкторе JavaInterviewHub. Другой вариант - инициализировать c, где он объявлен. Дополнительную информацию см. В ответе.

+0

Если вы это сделаете, у вас будет в общей сложности 3 экземпляра как «JavaInterviewHub», так и «Chicks», и нет необходимости * синхронизировать * 'Yack()'. – Andreas

+0

Причина, по которой программа создает несколько экземпляров 'JavaInterviewHub', не потому, что она создает новые потоки, подобные этому ...«Это из-за« нового JavaInterviewHub() ». Я понимаю, что основная часть« такого », о котором вы говорили, но эти новички нуждаются в большом количестве рук. Не путайте их, говоря« когда вы создаете новый поток ", если создание потока не является проблемой. –

Смежные вопросы