2012-09-20 29 views
1

我正在嘗試生產者/消費者問題,但我不知道爲什麼我在消費者內部獲得java.lang.NullPointerException我在消費者內部得到NullPointerException

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class Producer extends CommonClass implements Runnable { 

    private int producerNum; 

    Producer(PriorityBlockingQueue<Character> queue) { 
     queue = queue; 
    } 

    public void run() { 

     char ch; 

     for (ch = 'a'; ch <= 'z'; ch++) { 
      queue.add(ch); 
      System.out.println("Producer" + producerNum + "produced :" + ch); 
      try { 
       Thread.sleep((int) (Math.random() * 300)); 

      } catch (InterruptedException e) { 
       System.out.println("Error"); 
      } 

     } 

    } 

} 

這是我的消費類

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class Consumer extends CommonClass implements Runnable { 

    private int consumerNum; 

    Consumer(PriorityBlockingQueue<Character> queue) 
    { 
     queue = queue; 
    } 

    public void run() { 
     char c; 

     for (int i = 0; i < 27; i++) { 
      c = queue.poll(); 
      System.out.println("Consumer" + consumerNum + "consumed:" + c); 
      try { 
       Thread.sleep((int) (Math.random() * 300)); 
      } catch (InterruptedException e) { 
       System.out.println("Error"); 
      } 
     } 

    } 
} 

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class CommonClass { 

    PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>(); 

} 

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class SyncTest { 

    public static void main(String[] args) { 



     PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>(); 

     Producer p1 = new Producer(queue); 
     Thread t1 = new Thread(p1); 
     t1.start(); 

     Consumer c1 = new Consumer(queue); 
     Thread ct1 = new Thread(c1); 
     ct1.start(); 

    } 
} 

這是例外,我得到:

Exception in thread "Thread-1" java.lang.NullPointerException 
    at com.Consumer.run(Consumer.java:18) 
    at java.lang.Thread.run(Unknown Source) 
+0

當您發佈有關_any_異常的問題時,請在帖子中提供異常的前幾行,並指出_specifically_在您的代碼中異常行指向的位置。 – Gray

回答

7

這是迫在眉睫的問題:

Consumer(PriorityBlockingQueue<Character> queue) 
{ 
    queue = queue; 
} 

這是一個空操作語句,指定參數的值回發到自身。你想:

Consumer(PriorityBlockingQueue<Character> queue) 
{ 
    this.queue = queue; 
} 

一旦你定,你會然後有一個潛在的問題,因爲調用poll()(decalred在Queue),這將返回null如果隊列爲空。然後將該空引用拆箱,以將值分配給c變量(類型爲char)。

改爲使用take()(在BlockingQueue中聲明),它會阻塞。您可能也想要指定超時。

+0

非常感謝Jon Skeet現在的工作,我還有一個問題,如果我使用PriorityBlockingQueue作爲線程的源,我是否仍然需要分別在Consumer和Producer中使用wait和notify方法? – Pawan

+0

@PreethiJain:目前還不清楚「作爲線程來源」是什麼意思 - 但阻塞API的一般觀點是你*不必使用任何其他同步;只需使用'offer'和'take'即可。 –

+0

我的意思是說這是一個生產者和消費者線程,我們應該分別在COnsumer和Producer中使用wait和notify方法嗎? – Pawan

3

Use take instead of poll調查可能返回null。

JavaDoc#poll()

此隊列的頭,空如果此隊列爲空

使用put添加和採取get被阻塞的方法。