자바 buffer클래스 생산자 소비자 예제질문

조회수 515회
class Buffer
{
    private int data;//케잌
    private boolean empty=true;//케잌이 비었음표시
    public synchronized int get()//케잌을 사는 메서드
    {
        while(empty)
        {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        empty=true;
        notifyAll();//생산자를 깨우기
        return data;
    }
    public synchronized void put(int data) {//케잌을 생산하는메서드
        while(!empty)
        {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            empty=false;
            notifyAll();//소비자 깨우기
            this.data=data;
        }
    }
}
class Producer extends Thread 
{
    private Buffer buffer;
    public Producer(Buffer buffer)
    {
        this.buffer=buffer;
    }
    public void run()
    {
        for(int i=0;i<=10;i++)
        {
            buffer.put(i);//케잌생산
            System.out.println("생산자"+i+"케잌을 생산");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Cusumer extends Thread 
{
    private Buffer buffer;
    public Cusumer(Buffer buffer)
    {
        this.buffer=buffer;
    }
    public void run()
    {
        for(int i=0;i<=10;i++)
        {
            int data=buffer.get();//소비
            System.out.println("소비자가"+data+"번째 케잌을 소비");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class Ex01 {

    public static void main(String[] args) {
        Buffer obj = new Buffer();
        Producer p1 = new Producer(obj);
        Cusumer c1 = new Cusumer(obj);
        p1.start();
        c1.start();

    }

}

```제가 buffer클래스로 생산자가 1번째 케잌을 생산하면 소비자가 1번째 케잌을 소비하는 형식인데
이상하게도 생산자만 뜨고 소비자가 안뜨는데 제가 뭘 빼먹은건가요??


  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 문제가 뭔지만 알려드릴께요.

    ProducerBuffer.put()에서 케잌을 만들고, ConsumerBuffer.get()에서 케잌을 사는걸 만드셨군요?

    흐름은 Producer 쓰레드가 Producer.run()에서 i 번 째 케잌을 생산하고 1초 쉬는 동안, Consumer 쓰레드가 Consumer.run()에서 i 번 째 케잌을 사야하는걸로 보이구요.

    첫 번째 문제

    그런데 디버그를 돌려보니, 일단 소비자는 첫 Buffer.get() 호출 이 후 wait 상태를 아무도 안깨워줘서 계속 자고 있습니다. 😴

    Buffer.put()에서 notifyAll()로 소비자 깨우기를 의도하신걸로 보이나, 아래 코드를 보면:

    private boolean empty = true;// 케잌이 비었음표시
    
    ...
    
    while (!empty) {
        ...
        empty = false;
    

    멤버 변수 empty의 초기값이 true인 탓에 while문에 진입이 안됩니다. 그러니까 깨우기도 안되는거죠.

    두 번째 문제

    그럼 처음엔 무조건 while 문에 진입하도록 수정하면 문제가 해결되나? 아닙니다.
    ProducerConsumer 둘 다 wait() 부분에서 잠이 든 뒤 영원히 깨어나지 않습니다.

    요 두 가지 문제를 한 번 해결해보세요.

    그럼 이만 끟.


    만약에 타이밍을 조절해서 절묘하게 서로 깨우고 자고 하는걸 노리는거라면 다른 방법을 고려하시는게 좋습니다. 타이밍에 영향을 받는 프로그래밍은 컴퓨터의 성능에 영향을 받아 잘 돌아가다가도 안될 수도 있거든요.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)