2012-09-20 2 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"); 
      } 
     } 

    } 
} 

이이 내 클라이언트 프로그램입니다

package com ; 

import java.util.concurrent.PriorityBlockingQueue; 

public class CommonClass { 

    PriorityBlockingQueue<Character> queue = null; 

} 

내 CommonClass입니다

난이 실행할 때 451,515,
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(); 

    } 
} 

는 난이 E 및 F 알파벳의 경우에 출력

Producer0produced :a 
Consumer0consumed:a 

Producer0produced :b 
Consumer0consumed:b 

Producer0produced :c 
Consumer0consumed:c 

Producer0produced :d 
Consumer0consumed:d 

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

으로 얻는다.

이 출력에 문제가 있습니까 ?? 나는 Producer0produced 문장을 동시에 두 번 보았고 Consumer0consumed 문 다음에 e와 f라는 문자를 동시에 출력했다.

이 코드를 사용하면 제작자가 제작 한 정보가 누락 될 수 있습니다.

제발 조언 ??

감사합니다.

+0

같은 코드이지만 질문이 다르다면 어떤 질문은 여러 가지 질문을하지 말고 하나의 실에서 말하면됩니다. – Pawan

+0

여러 스레드가 임의의 순서로 동시에 작업을 수행하도록 설계되었음을 잊지 마십시오. 이 행동을 보는 것은 좋은 일입니다. 시작과 마찬가지로 번갈아 가며 본 것이 있다면 실제로는 여러 스레드가 필요하지 않다고 말합니다. –

답변

2

이 출력에 문제가 있습니까?

아니요. 생산자 스레드는 소비자가 첫 번째 항목을 소비하기 전에 두 번째 항목을 생성하기 만했습니다. 그것은 전적으로 자연 스럽습니다. 특히 당신이 임의의 시간 동안 자고있을 때.

물론 큐의 상한값을 지정하고 add 대신 offer을 사용하여 큐가 가득 찼던 상황을 감지 할 수 있지만 표시 한 결과는 문제가 없습니다.

0

나는 Producer0produced 문장을 동시에 두 번 본 다음 Consumer0consumed 문을 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 소비자 버전이 단순화되었습니다.

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은 필수는 아니지만, 프로듀서 스레드가 연속 요청을 할 수있는 히브 트래픽 웹 응용 프로그램에서 동일한 코드를 사용합니다. 서버에 대한 데이터, 그래서 내가 브라우저를 실시간 시나리오에 정착하기 위해 Thread.sleep을 사용합니다 – Pawan

+1

왜'SynchronousQueue'를 사용하지 않으면 소비자가 있지 않으면 put이 차단됩니다. –