2014-11-20 2 views
0

/* 제작자 만 실행하고 소비자가 아무것도 소비하지 않을 때마다 여기에서 무엇이 잘못 되었습니까? 이 코드에서 무엇이 잘못되었는지 설명해주십시오. Java : 멀티 스레딩

내 예상 결과

: 생산자 제작 한 항목은 다음 소비자가 해당 항목 *을 소비하는 당신이 sycnhronize 기다려 그렇지 객체 프로듀서를 들어, 사용 목록을 통지 할 필요가 모든/

import java.util.ArrayList; 

public class ConsumerAndProducerMain 
{ 
    public static void main(String[] args) throws InterruptedException 
    { 
     int MAX_SIZE = 10; 
     ArrayList<Integer> list = new ArrayList<Integer>(10); 
     final Producer producer = new Producer(MAX_SIZE, list); 
     final Consumer consumer = new Consumer(MAX_SIZE, list); 
     Thread t1 = new Thread(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       try 
       { 
        producer.producer(); 
       } 
       catch (InterruptedException e) 
       { 
        System.out.println("Producer : Exception occured because of multi threading..."); 
        e.printStackTrace(); 
       } 
      } 
     }); 
     Thread t2 = new Thread(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       try 
       { 
        consumer.consumer(); 
       } 
       catch (InterruptedException e) 
       { 
        System.out.println("Consumer : Exception occured because of multi threading..."); 
        e.printStackTrace(); 
       } 
      } 
     }); 
     t1.start(); 
     t2.start(); 
     t1.join(); 
     t2.join(); 
     System.out.println("Program terminated.."); 
    } 
} 

class Producer { 
    int size; 
    ArrayList<Integer> list; 
    public Producer(int size, ArrayList<Integer> list) 
    { 
     this.size = size; 
     this.list = list; 
    } 
    public void producer() throws InterruptedException{ 
     int value = 0; 
     while(true){ 
      synchronized (this) 
      { 
       if(list.size() == size){ 
        System.out.println("Producer : List is full"); 
        wait(); 
       }else{ 
        list.add(++value); 
        Thread.sleep(200); 
        notify(); 
        System.out.println("Value produce by the producer : "+value); 
       } 
      } 
     } 
    } 
} 

class Consumer { 
    int size; 
    ArrayList<Integer> list; 
    public Consumer(int size, ArrayList<Integer> list) 
    { 
     this.size = size; 
     this.list = list; 
    } 
    public void consumer() throws InterruptedException{ 
     while(true){ 
      synchronized (this) 
      { 
       if(list.isEmpty()){ 
        System.out.println("Consumer : List is empty"); 
        wait(); 
       }else{ 
        int removedItem = list.remove(list.size()); 
        Thread.sleep(5000); 
        notify(); 
        System.out.println("Value consumed by the consumer : "+removedItem); 
       } 
      } 
     } 
    } 
} 
+1

이는 Java 동시성에 대한 소개 자료를 읽음으로써 해결되어야합니다. 각 스레드는 자체 잠금을 사용하므로 조정이 발생하지 않습니다. –

+0

Marko가 만들고있는 요지는 '대기'하기 위해'notify '가 작동하기 위해서, 그들은 같은 객체를 알리거나 대기해야한다는 것입니다. 그러나 각 객체는 공통 객체 대신 자체적으로 잠그고 있습니다. –

+0

유사 [동일한 스레드가 두 개의 동기화 된 메소드를 동일한 객체에서 실행할 수 있음] (http://stackoverflow.com/questions/26361367/same-thread-isable-to-execute-on-same-objects-two -synchronized-methods/26362523 # 26362523) – OO7

답변

0

첫 번째와 당신이하는 소비자.

프로듀서 :

final ArrayList<Integer> list; 
// ... 
synchronized (list) { 
    if (list.size() == size) { 
    System.out.println("Producer : List is full"); 
    list.wait(); 
    } else { 
    list.add(++value); 
    Thread.sleep(200); 
    list.notify(); 
    System.out.println("Value produce by the producer : " + value); 
    } 
} 

소비자 : 당신의 예상 결과 (1 개 항목은 다음 소비자가 소비하는 생산자의 생산을 위해

Value produce by the producer : 1 
Value produce by the producer : 2 
Value produce by the producer : 3 
Value produce by the producer : 4 
Value produce by the producer : 5 
Value produce by the producer : 6 
Value produce by the producer : 7 
Value produce by the producer : 8 
Value produce by the producer : 9 
Value produce by the producer : 10 
Producer : List is full 
Value consumed by the consumer : 10 
Value consumed by the consumer : 9 
Value consumed by the consumer : 8 
... 

:

final ArrayList<Integer> list; 
// ... 
synchronized (list) { 
    if (list.isEmpty()) { 
    System.out.println("Consumer : List is empty"); 
    list.wait(); 
    } else { 
    int removedItem = list.remove(list.size() - 1); 
    Thread.sleep(200); 
    list.notify(); 
    System.out.println("Value consumed by the consumer : " + removedItem); 
    } 
} 

출력의 모양입니다 item) wait의 순서로 로직을 변경하고 알림을해야합니다. 프로듀서가 항목을 추가하고 알림을 보내고 다음을 기다립니다. r Consumer notify, Consumer가 Producer notify를 기다리고 1 개 항목을 소비 한 다음 Producer notify를 다시 기다립니다.

+0

"... 당신은 sycnhronize, 기다려야하고 목록에 대한 알림을해야합니다 ..."사실, 스레드는 동기화를 위해 모든 개체를 사용할 수 있습니다. 공유하는 목록 일 필요는 없습니다. 목록을 사용하면 편리하기 때문에 이미 공유하고 있기 때문에 편리합니다. 그러나 크고 복잡한 시스템에서는 데이터를 보유하고있는 다른 개체와 다른 개체를 동기화하는 것이 좋습니다. –

+0

안녕하세요, Producer에서 호출 된 list.wait() 메서드에서 오류가 발생하고 arraylist 크기가 10에서 20으로 늘어날 때마다 목록에서 알림 및 대기 메서드를 호출하려고 시도했지만 여전히 동일한 오류가 발생합니다. 스레드 "스레드 1"java.lang.IndexOutOfBoundsException에서 '예외 : 인덱스 : 10, 크기 : java.util.ArrayList.RangeCheck 10 \t (ArrayList.java:547) 인 java.util.ArrayList에서 \t. 제거 (ArrayList.java:387) Consumer.consumer에서 \t (ConsumerAndProducerMain.java:112) java.lang.Thread.run (Thread.java에서 ConsumerAndProducerMain $ 2.run (ConsumerAndProducerMain.java:41) \t에서 \t : 619)' – Girish

+0

"list.wait() statement"as "list.wait() statement"읽으십시오. – Girish