자바 프로그래밍 독학중인데영

jabiers의 이미지

여기에 이런 질문 해도 됄런지.. ㅎㅎ;;
책을 보면서 자바를 독학 하고 있습니다.
공부하면서 질문좀 하려구요. ^^
밑에는 소스 입니다.

class Producer extends Thread {
private Buffer blank;

public Producer(Buffer blank) {
this.blank = blank ;
}
public void run() {
for (int i=0; i<10;i++) {
blank.put(i);
// 생산자 스레드는 계속해서 put() 메소드 호출
try {
sleep((int)(Math.random() * 100 ));
} catch (InterruptedException e) { }
}
}
}

class Consumer extends Thread {
private Buffer blank;

public Consumer(Buffer c) {
blank = c;
}
public void run() {
int value = 0;
for (int i = 0 ; i < 10 ; i++ ) {
value = blank.get();
// 소비자 스레드는 계속 get() 메소드를 호출
}
}
}

class Buffer {
private int contents;
private boolean available = false;
// flag 역할을 하는 available 변수의 초기값을 false로 설정
// 처음에는 생산자가 먼저 데이터를 가져다 놓아야 한다

public synchronized int get() {
// 임계영역을 지정하는 메소드. 버퍼로부터 데이터를 get
while (available == false ) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("소비자########## : 소비 " + contents);
notify();
available = false;

// 데이터를 반환하기전에 put()에 들어가기위해
// 기다리는 메소드를 깨운다
return contents;
}
public synchronized void put(int value) {
// 임계영역을 지정하는 메소드. 버퍼에 데이터를 put
while (available == true ) {
try {
wait();
} catch (InterruptedException e) {}
}
contents = value;
System.out.println("생산자########## : 생산 " + contents);
notify();
available = true;
// 값을 저장하고 get() 메소드에 들어가기 위해
// 대기하고 있는 스레드중에 하나를 깨운다
}
}

public class ProducerConsumer {
public static void main(String args[]) {
Buffer c = new Buffer();
Producer p1 = new Producer(c);
Consumer c1 = new Consumer(c);
// 생산자와 소비자 스레드 객체를 생성
// 버퍼 객체 c를 매개변수로 생성한다
p1.start() ;
c1.start() ;
}
}

이걸 실행하면
생산 0
소비 0
생산 1
소비 1
...
생산 9
생산 9

가 나옵니다. (간략하게 적엇습니다. ㅎㅎ;;)

연습문제를 혼자 풀어보고 있는데 문제가 이 예제를 이용해서
생산 소비가 번갈아 나오는것이 아닌
생산이 연달아 나올수도 있고 소비가 연달아 나올수 있는 (생산이 0 번인데 소비가 있을수 없고 생산이 2번밖에 없는데 소비가 3번 이상 못나오는)
그런걸 짜래영...;;; 흰트로써 boolean 이 아닌 딴걸 주라는데 도저히 모르겟네여 -_-;;;
책만 보고 하다가 답두 없구...몇일 잡구 있엇더니 오기가 생기네요 -_-;;
도저히 궁금해서 고수님들에게 문의해 봅니다.

skyoon의 이미지

작성했던...한 3~4년 전에 작성했던거라 기억이 가물가물하네요. 참고하세요. 설명은 패스~ -_-;;

// 동기화 스택 클래스
class SyncStack {
private int index = 0;
private char [] buffer = new char[6]; // 스택의 크기는 6개

// 스택으로부터 꺼냄
public synchronized char pop() { //
while (index == 0) { // 하나도 없으면 기다림.
try {
this.wait();
} catch (InterruptedException e) { }
}
this.notify(); // 아니면, 수행
index--;
printStack();
System.out.println("\t Consumed: " + buffer

    );
    return buffer
      ;
      }

      // 스택에 넣음
      public synchronized void push(char c) {
      while (index == buffer.length) { // 가득 찼으면 기다림.
      try {
      this.wait();
      } catch (InterruptedException e) { }
      }
      this.notify(); // 아니면, 수행
      buffer

        = c;
        printStack();
        System.out.println("\t Produced: " + c);
        index++;
        }

        public void printStack() {
        System.out.print("Stack: ");
        for (int i=0; i if (i <= index) System.out.print(buffer[i] + " ");
        else System.out.print(" ");
        }
        }

        // 생산자 클래스 (스택에 값을 계속 넣음)
        class Producer implements Runnable {
        SyncStack theStack;
        public Producer(SyncStack s) {
        theStack = s;
        }
        public void run() {
        char c;
        for (int i = 0; i < 10; i++) {
        c = (char)(Math.random() * 26 + 'A');
        theStack.push(c);
        try {
        Thread.sleep((int)(Math.random() * 100));
        } catch (InterruptedException e) { }
        }
        }
        }

        // 소비자 클래스 (스택에서 값을 계속 가져감)
        // 생산자보다 소비자의 속도가 늦어서 스택에 쌓이게 함.
        class Consumer implements Runnable {
        SyncStack theStack;
        public Consumer(SyncStack s) {
        theStack = s;
        }
        public void run() {
        char c;
        for (int i=0; i<10; i++) {
        c = theStack.pop();
        try {
        Thread.sleep((int)(Math.random() * 300));
        } catch (InterruptedException e) { }
        }
        }
        }

        public class ProducerConsumer {
        public static void main(String args[]) {
        SyncStack stack = new SyncStack();
        Runnable producer = new Producer(stack);
        Runnable consumer = new Consumer(stack);
        Thread t1 = new Thread(producer);
        Thread t2 = new Thread(consumer);
        t1.start();
        t2.start();
        }
        }

        jabiers의 이미지

        skyoon 님 감사합니다. ^^
        추가 적인 질문으로...
        class SyncStack {
        private int index = 0;
        private int [] buffer = new int[6]; // 스택의 크기는 6개// 스택으로부터 꺼냄
        public synchronized int pop() { //
        while (index == 0) { // 하나도 없으면 기다림.
        try {
        this.wait();
        } catch (InterruptedException e) { }
        }
        this.notify(); // 아니면, 수행
        index--;
        System.out.println("소비자########## : 소비" + buffer);
        return buffer[2];
        }

        // 스택에 넣음
        public synchronized void push(int c) {
        while (index == buffer.length) { // 가득 찼으면 기다림.
        try {
        this.wait();
        } catch (InterruptedException e) { }
        }
        this.notify(); // 아니면, 수행
        int buffer = c;
        System.out.println("생산자########## : 생산" + c);
        index++;
        }

        // 생산자 클래스 (스택에 값을 계속 넣음)
        class Producer implements Runnable {
        SyncStack theStack;
        public Producer(SyncStack s) {
        theStack = s;
        }
        public void run() {
        int c;
        for (int i = 0; i < 10; i++) {
        c = (int)(Math.random() * 26 + 'A');
        theStack.push(c);
        try {
        Thread.sleep((int)(Math.random() * 100));
        } catch (InterruptedException e) { }
        }
        }
        }

        // 소비자 클래스 (스택에서 값을 계속 가져감)
        // 생산자보다 소비자의 속도가 늦어서 스택에 쌓이게 함.
        class Consumer implements Runnable {
        SyncStack theStack;
        public Consumer(SyncStack s) {
        theStack = s;
        }
        public void run() {
        int c;
        for (int i=0; i<10; i++) {
        c = theStack.pop();
        try {
        Thread.sleep((int)(Math.random() * 300));
        } catch (InterruptedException e) { }
        }
        }
        }
        }
        public class ProducerConsumer {
        public static void main(String args[]) {
        SyncStack stack = new SyncStack();
        Runnable producer = new Producer(stack);
        Runnable consumer = new Consumer(stack);
        Thread t1 = new Thread(producer);
        Thread t2 = new Thread(consumer);
        t1.start();
        t2.start();
        }
        }

        위 소스 약간 변경하였습니다. 이걸 실행하면...

        ---------- Java ----------
        생산자########## : 생산75
        소비자########## : 소비[I@1b67f74
        생산자########## : 생산77
        생산자########## : 생산88
        생산자########## : 생산67
        생산자########## : 생산78
        소비자########## : 소비[I@1b67f74
        생산자########## : 생산73
        생산자########## : 생산88
        소비자########## : 소비[I@1b67f74
        생산자########## : 생산78
        소비자########## : 소비[I@1b67f74
        생산자########## : 생산72
        생산자########## : 생산77
        소비자########## : 소비[I@1b67f74
        소비자########## : 소비[I@1b67f74
        소비자########## : 소비[I@1b67f74
        소비자########## : 소비[I@1b67f74
        소비자########## : 소비[I@1b67f74
        소비자########## : 소비[I@1b67f74
        Normal Termination
        출력 완료 (2초 경과).

        이렇게 뜨네요...
        생산을 처음 햇을때 0 주고 두번째 1 주고... 마지막엔 9 소비도 마찬가지로...
        해주려고 하는데 어딜 건드려야 됄지 막막하네요 ^6;;

        댓글 달기

        Filtered HTML

        • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
        • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
        • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
        • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

        BBCode

        • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
        • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
        • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
        • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

        Textile

        • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
        • You can use Textile markup to format text.
        • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

        Markdown

        • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
        • Quick Tips:
          • Two or more spaces at a line's end = Line break
          • Double returns = Paragraph
          • *Single asterisks* or _single underscores_ = Emphasis
          • **Double** or __double__ = Strong
          • This is [a link](http://the.link.example.com "The optional title text")
          For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
        • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
        • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

        Plain text

        • HTML 태그를 사용할 수 없습니다.
        • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
        • 줄과 단락은 자동으로 분리됩니다.
        댓글 첨부 파일
        이 댓글에 이미지나 파일을 업로드 합니다.
        파일 크기는 8 MB보다 작아야 합니다.
        허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
        CAPTCHA
        이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.