인프런 커뮤니티 질문&답변

lgh8079님의 프로필 이미지

작성한 질문수

김영한의 실전 자바 - 고급 1편, 멀티스레드와 동시성

생산자 소비자 문제 - 예제1 분석 - 생산자 우선

56강에 대한 질문입니다(BoundedMain).

24.09.10 09:51 작성

·

51

0

[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
package thread.bounded; import static util.MyLogger.log; public class ProducerTask implements Runnable { private BoundedQueue queue; private String request; public ProducerTask(BoundedQueue queue, String request) { this.queue = queue; this.request = request; } @Override public void run() { log("[생산 시도] " + request + " -> " + queue); log("[생산 완료] " + request + " -> " + queue); } }

package thread.bounded; import static util.MyLogger.log; public class ConsumerTask implements Runnable { private BoundedQueue queue; public ConsumerTask(BoundedQueue queue) { this.queue = queue; } @Override public void run() { log("[소비 시도] ? <- " + queue); String data = queue.take(); log("[소비 완료] " + data + " <- " + queue); } }

package thread.bounded; public interface BoundedQueue { void put(String data); String take(); }

package thread.bounded; import java.util.ArrayList; import java.util.List; import static util.MyLogger.log; import static util.ThreadUtils.sleep; public class BoundedMain { public static void main(String[] args) { // 1. BoundedQueue 선택 BoundedQueue queue = new BoundedQueueV1(2); // 2. 생산자, 소비자 실행 순서 선택, 반드시 하나만 선택! producerFirst(queue); // 생산자 먼저 실행 //consumerFirst(queue); // 소비자 먼저 실행 } private static void producerFirst(BoundedQueue queue) { log("== [생산자 먼저 실행] 시작, " + queue.getClass().getSimpleName() + " =="); List<Thread> threads = new ArrayList<>(); startProducer(queue, threads); printAllState(queue, threads); startConsumer(queue, threads); printAllState(queue, threads); log("== [생산자 먼저 실행] 종료, " + queue.getClass().getSimpleName() + " =="); } private static void consumerFirst(BoundedQueue queue) { log("== [소비자 먼저 실행] 시작, " + queue.getClass().getSimpleName() + " =="); List<Thread> threads = new ArrayList<>(); startConsumer(queue, threads); printAllState(queue, threads); startProducer(queue, threads); printAllState(queue, threads); log("== [소비자 먼저 실행] 종료, " + queue.getClass().getSimpleName() + " =="); } private static void startProducer(BoundedQueue queue, List<Thread> threads) { System.out.println(); log("생산자 시작"); for (int i = 1; i <= 3; i++) { Thread producer = new Thread(new ProducerTask(queue, "data" + i), "producer" + i); threads.add(producer); producer.start(); sleep(100); } } private static void startConsumer(BoundedQueue queue, List<Thread> threads) { System.out.println(); log("소비자 시작"); for (int i = 1; i <= 3; i++) { Thread consumer = new Thread(new ConsumerTask(queue), "consumer" + i); threads.add(consumer); consumer.start(); sleep(100); } } private static void printAllState(BoundedQueue queue, List<Thread> threads) { System.out.println(); log("현재 상태 출력, 큐 데이터: " + queue); for (Thread thread : threads) { log(thread.getName() + ": " + thread.getState()); } } }

package thread.bounded; import java.util.ArrayDeque; import java.util.Queue; import static util.MyLogger.log; public class BoundedQueueV1 implements BoundedQueue { private final Queue<String> queue = new ArrayDeque<>(); private final int max; public BoundedQueueV1(int max) { this.max = max; } @Override public synchronized void put(String data) { if (queue.size() == max) { log("[put] 큐가 가득 참, 버림: " + data); return; } queue.offer(data); } @Override public synchronized String take() { if (queue.isEmpty()) { return null; } return queue.poll(); } @Override public String toString() { return queue.toString(); } }

C:\Users\lgh80\.jdks\temurin-21.0.4\bin\java.exe --enable-preview "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\lib\idea_rt.jar=52674:C:\Program Files\JetBrains\IntelliJ IDEA 2024.1.4\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\java-adv1\out\production\java-adv1 thread.bounded.BoundedMain

09:38:16.411 [ main] == [생산자 먼저 실행] 시작, BoundedQueueV1 ==

09:38:16.413 [ main] 생산자 시작

09:38:16.424 [producer1] [생산 시도] data1 -> []

09:38:16.425 [producer1] [생산 완료] data1 -> []

09:38:16.531 [producer2] [생산 시도] data2 -> []

09:38:16.532 [producer2] [생산 완료] data2 -> []

09:38:16.642 [producer3] [생산 시도] data3 -> []

09:38:16.642 [producer3] [생산 완료] data3 -> []

09:38:16.752 [ main] 현재 상태 출력, 큐 데이터: []

09:38:16.754 [ main] producer1: TERMINATED

09:38:16.754 [ main] producer2: TERMINATED

09:38:16.754 [ main] producer3: TERMINATED

09:38:16.755 [ main] 소비자 시작

09:38:16.757 [consumer1] [소비 시도] ? <- []

09:38:16.757 [consumer1] [소비 완료] null <- []

09:38:16.864 [consumer2] [소비 시도] ? <- []

09:38:16.865 [consumer2] [소비 완료] null <- []

09:38:16.974 [consumer3] [소비 시도] ? <- []

09:38:16.975 [consumer3] [소비 완료] null <- []

09:38:17.085 [ main] 현재 상태 출력, 큐 데이터: []

09:38:17.085 [ main] producer1: TERMINATED

09:38:17.086 [ main] producer2: TERMINATED

09:38:17.086 [ main] producer3: TERMINATED

09:38:17.086 [ main] consumer1: TERMINATED

09:38:17.087 [ main] consumer2: TERMINATED

09:38:17.087 [ main] consumer3: TERMINATED

09:38:17.087 [ main] == [생산자 먼저 실행] 종료, BoundedQueueV1 ==

Process finished with exit code 0



이런 식으로 출력이 뜨는데 강의 내용에 나와있는 로그 창이랑 많이 달라서 강의 코드랑도 비교해봤는데 어디에서 문제가 있는 건지 잘 모르겠습니다.

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

2024. 09. 11. 18:35

안녕하세요. BoundedQueue님

도움을 드리고 싶지만 질문 내용만으로는 답변을 드리기 어렵습니다.

실제 동작하는 전체 프로젝트를 ZIP파일로 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

 

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 문제 영역을 실행할 수 있는 방법

2. 문제가 어떻게 나타나는지에 대한 상세한 설명 (오류 화면, 오류 로그 포함)

링크: 공식 서포터즈

링크: 자주하는 질문

감사합니다.

lgh8079님의 프로필 이미지

작성한 질문수

질문하기