2012-09-20 194 views
2

可能重複:
I am getting NullPointerException inside ConsumerNullPointerException異常

難道這被認爲是在生產中的錯誤,消費者方案?

這是我的監製類。

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class Producer extends CommonClass implements Runnable { 
    private SyncronizedStack stack; 
    private int producerNum; 

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

    public void run() { 

     char ch; 

     for (ch = 'a'; ch <= 'f'; 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) { 
     this.queue = queue; 
    } 

    public void run() { 
     char c; 
     for (int i = 0; i < 7; i++) { 
      try { 
       c = queue.take(); 
       System.out.println("Consumer" + consumerNum + "consumed:" + c); 
      } catch (Exception e1) { 
       e1.printStackTrace(); 
      } 
      try { 
       Thread.sleep((int) (Math.random() * 300)); 
      } catch (InterruptedException e) { 
       System.out.println("Error"); 
      } 
     } 

    } 
} 

這是我CommonClass

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class CommonClass { 

    PriorityBlockingQueue<Character> queue = null; 

} 

這是我的客戶端程序

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class SyncTest { 

    public static void main(String[] args) { 

     CommonClass cs = new CommonClass(); 

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

    } 
} 

當我運行此我得到輸出

Producer0produced :a 
Consumer0consumed:a 

Producer0produced :b 
Consumer0consumed:b 

Producer0produced :c 
Consumer0consumed:c 

Producer0produced :d 
Consumer0consumed:d 

Producer0produced :e 
Producer0produced :f 
Consumer0consumed:e 
Consumer0consumed:f 

這是E和F字母的情況。

是否有這個輸出的任何問題?因爲我看到Producer0同時生成了兩個語句,然後同時跟着Consumer0消息語句爲字母e和f。

我擔心,這個代碼我會想念由生產者產生的任何信息?

請指教?

謝謝意見。

+0

相同的代碼,但問題是不同的,有些人說不要問多個問題,在單線程中,現在你說這個。 – Pawan

+0

不要忘記,多個線程被設計爲以任何順序同時執行任務。看到這種行爲是件好事。如果你只是在開始時看到它交替,它說你並不需要多線程。 –

回答

2

是否有這個輸出的任何問題?

沒有。您的生產者線程只是設法在消費者設法消費第一個產品之前生成第二個產品。這是完全自然的,特別是當你隨機睡覺時。

當然,你可能想給一個上限,以您的隊列 - 然後用offer而不是add檢測,其中隊列已滿的情況 - 但你顯示的輸出是罰款。

0

因爲我看到聲明Producer0同時產生了兩個時間,然後同時跟隨着Consumer0消耗語句中的字母e和f。

不,這是可以預料的。您正在演示多個線程的典型異步行爲。製片人在消費者睡覺時能夠出示2封信。

這是將要發生特別是考慮到兼顧生產者和消費者都在做隨機睡覺:

Thread.sleep((int) (Math.random() * 300)); 

但即使沒有睡覺,這種不對稱的行爲,預計螺紋程序。

+0

任何人都想解釋-1? – Gray

+0

不是我,但也許是因爲這種行爲被描述爲'競爭條件' - 通常用於描述由於同步錯誤導致的不正確行爲的短語。此代碼正常工作(如果由於用戶中的Sleep()調用而導致效果不佳)。 –

+0

呵呵。對我來說,競爭條件並不意味着錯誤。它只是關於異步行爲。他的節目是製作人和消費者之間競賽的完美定義。感謝@Martin。 – Gray

0

這是一個錯誤?

答案 - 發生這種情況是因爲您正在添加不必要的睡眠。

Thread.sleep((int) (Math.random() * 300)); 

我簡化了下面的Producer consumer的版本。

public class Example { 

public static class Producer implements Runnable { 
    private PriorityBlockingQueue<Character> queue; 

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

    public void run() { 
     char ch; 
     for (ch = 'a'; ch <= 'f'; ch++) { 
      queue.put(ch); 
     } 
    } 
} 

public static class Consumer implements Runnable { 

    private PriorityBlockingQueue<Character> queue; 

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

    public void run() { 
     for (int i = 0; i < 7; i++) { 
      try { 
       System.out.println("Consumer take :" + queue.take()); 
      } catch (InterruptedException e) { 
       Thread.currentThread().interrupt();// Propagate interrupt 
      } 
     } 
    } 
} 

public static void main(String[] args) { 
    ExecutorService executorService = Executors.newFixedThreadPool(2); 
    PriorityBlockingQueue<Character> queue = new PriorityBlockingQueue<Character>(7); 
    executorService.execute(new Producer(queue)); 
    executorService.execute(new Consumer(queue)); 
    executorService.shutdown(); 
} 

} 
+0

AmitD,非常感謝代碼,對於當前程序我同意Thread.sleep不是必需的,但我將使用相同的代碼,在基於流量的基於Web的應用程序中,生產者線程將使連續請求服務器數據,所以我將使用Thread.sleep,以便瀏覽器實時安置下來 – Pawan

+1

爲什麼不使用'SynchronousQueue',那麼除非有消費者,否則你的put會被阻塞。 –