자바 프로그래밍 독학중인데영
여기에 이런 질문 해도 됄런지.. ㅎㅎ;;
책을 보면서 자바를 독학 하고 있습니다.
공부하면서 질문좀 하려구요. ^^
밑에는 소스 입니다.
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 이 아닌 딴걸 주라는데 도저히 모르겟네여 -_-;;;
책만 보고 하다가 답두 없구...몇일 잡구 있엇더니 오기가 생기네요 -_-;;
도저히 궁금해서 고수님들에게 문의해 봅니다.
오래전...
작성했던...한 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();
}
}
킁..;;;
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;;
댓글 달기