Skip to content
This repository was archived by the owner on Dec 26, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public void run() {
System.out.printf("%d 번 창구에서 %d 번 고객님의 업무가 처리 완료되었습니다. %n", this.deskNumber, currentCustomerNumber);
System.out.printf("%d 번 창구에서 서비스 대기중 입니다... %n", this.deskNumber);
}
isInterrupted();
interrupted();

} catch (InterruptedException e) {
System.out.println(e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.nhnacademy.yunhwa._10_연습문제;


/*
* Exam-03. 매장에 물건을 구매하는 소비자(Consumer)을 정의하라.
* - 소비자는 매장에 입장 후 물건을 구매할 수 있다.
* - 매장에는 입장 인원 제한이 있으므로, 인원 초과시 기다린다.
* - 매장에 입장하면 물건을 구매하고, 퇴장한다.
* - 1~10초 간격으로 구매한다.
* */

import java.util.concurrent.ThreadLocalRandom;

public class Consumer implements Runnable {
String name;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

접근제어자를 default로 해주신 이유가 있을까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

접근제어자를 달아 주시면 좋을 것 같습니다!

Store store;

public Consumer(String name, Store store) {
this.name = name;
this.store = store;
}

@Override
public void run() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Main에서 Consumer를 Interrupt를 해줄 때 결과 값에 중지합니다가 뜬 후에 물건 판매완료와 퇴장하는 결과값이 나오는 의도로 하신 이유가 있을까여?? deadlock이 걸릴 가능성을 생각하셔서 하신건가용?

while (!Thread.currentThread().isInterrupted()) {
store.enter(); // 매장에 입장

// 물건을 1~10초 간격으로 구매 (store 입장에서는 판매)
int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1;
try {
Thread.sleep(randomInterval * 1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 이 중지됩니다.");
Thread.currentThread().interrupt();
}
store.sell();

store.exit(); // 퇴장
}
}
}
131 changes: 131 additions & 0 deletions Thread/src/main/java/com/nhnacademy/yunhwa/_10_연습문제/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package com.nhnacademy.yunhwa._10_연습문제;

public class Main {
public static void main(String[] args) {
Store store = new Store();

Thread producer1 = new Thread(new Producer(store), "producer1");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음엔 반복문을 활용해보세요

Thread producer2 = new Thread(new Producer(store), "producer2");
Thread producer3 = new Thread(new Producer(store), "producer3");
Thread producer4 = new Thread(new Producer(store), "producer4");
Thread producer5 = new Thread(new Producer(store), "producer5");
Thread producer6 = new Thread(new Producer(store), "producer6");
Thread producer7 = new Thread(new Producer(store), "producer7");

Thread consumer1 = new Thread(new Consumer("consumer1", store), "consumer1");
Thread consumer2 = new Thread(new Consumer("consumer2", store), "consumer2");
Thread consumer3 = new Thread(new Consumer("consumer3", store), "consumer3");
Thread consumer4 = new Thread(new Consumer("consumer4", store), "consumer4");
Thread consumer5 = new Thread(new Consumer("consumer5", store), "consumer5");
Thread consumer6 = new Thread(new Consumer("consumer6", store), "consumer6");
Thread consumer7 = new Thread(new Consumer("consumer7", store), "consumer7");
Thread consumer8 = new Thread(new Consumer("consumer8", store), "consumer8");


producer1.start();
consumer1.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

producer2.start();
consumer2.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

consumer3.start();
producer3.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

producer4.start();
consumer4.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

consumer5.start();
producer5.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

producer6.start();
consumer6.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

consumer7.start();
producer7.start();

try {
Thread.sleep(1000 * 2);
} catch (InterruptedException ignore) {
}

consumer8.start();





System.out.println("메인 쓰레드에서 10초 대기 들어갑니다.");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException ignore) {
}

consumer1.interrupt();
producer1.interrupt();

System.out.println("메인 쓰레드에서 3초 대기 들어갑니다.");
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException ignore) {
}

consumer2.interrupt();
producer4.interrupt();
consumer3.interrupt();
producer2.interrupt();

System.out.println("메인 쓰레드에서 10초 대기 들어갑니다.");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException ignore) {
}

consumer4.interrupt();
producer3.interrupt();

System.out.println("메인 쓰레드에서 10초 대기 들어갑니다.");
try {
Thread.sleep(1000 * 10);
} catch (InterruptedException ignore) {
}
consumer5.interrupt();
producer5.interrupt();

consumer6.interrupt();
producer6.interrupt();

producer7.interrupt();
consumer7.interrupt();
consumer8.interrupt();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.nhnacademy.yunhwa._10_연습문제;

/*
* Exam-02. 매장에 물건을 납품하는 생산자(Producer)을 정의하라.
* - 생산자는 매장에 물건이 부족하지 않도록 채워둔다.
* - 물건은 1~10초 간격으로 채운다.
* - Thread내에서 난수 생성을 위해서는 ThreadLocalRandom.current().nextInt()를 사용하면 된다.
* */

import java.util.concurrent.ThreadLocalRandom;

public class Producer implements Runnable { // 매장에 물건을 납품하는 생산자(Producer)

private Store store;

public Producer(Store store) {
this.store = store;
}


@Override
public void run() {
while (! Thread.currentThread().isInterrupted()) {
try {
store.buy();
System.out.println(Thread.currentThread().getName() + " 가 물건 납품을 완료했습니다.");
int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1;
Thread.sleep(randomInterval * 1000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 이 중지됩니다.");
Thread.currentThread().interrupt();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.nhnacademy.yunhwa._10_연습문제;

public class Product {
private String name;
private int price;

public Product(String name, int price) {
this.name = name;
this.price = price;
}

public String getName() {
return this.name;
}

public int getPrice() {
return this.price;
}

}
116 changes: 116 additions & 0 deletions Thread/src/main/java/com/nhnacademy/yunhwa/_10_연습문제/Store.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.nhnacademy.yunhwa._10_연습문제;

/*
* Exam- 01. 마트 내에 위치한 매장(Store) 을 정의하라.
* 매장은 물건을 납품 받아서 판매한다.
* 매장에는 최대 10개의 물건만 전시할 수 있다.
* 매장은 최대 5명까지만 동시 입장 가능하다.
* 매장에서 물건 구매는 동시에 1명만 가능하다.
* 매장에서 물건 판매 후 빈 공간이 생기면 생산자에게 알려준다.
* 매장에서 물건 납품은 동시에 1명만 가능하다. v
* 매장에서 물건이 들어오면 소비자에게 알려준다.
* */

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class Store { // 마트 내에 위치한 매장(Store)

private List<Product> products;
private final int DISPLAYABLE_CAPACITY;
private final int ENTERABLE_CAPACITY;
private int enteredPersonCount;
private int producedCount;
private Queue<Thread> waitingList;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 자료형의 필요성에 대해 생각하게 됩니다

add를 하지만 pop을 하지 않으니 queue여야 하는 이유가 있을까요

Thread를 순차적으로 깨워주기 위해서라기엔 이 자료형이 비어있을 때 모든 쓰레드를 notifyAll하는 구조이고... 만약 이 의도대로라면 pop을 하고, 그 자료형을 깨워주는 식으로 하면 어떨까싶습니다

실제로 구현될 지는 미지수지만요


public Store() {
this.products = new ArrayList<>();
this.DISPLAYABLE_CAPACITY = 10; // 매장에는 최대 10개의 물건만 전시 가능
this.ENTERABLE_CAPACITY = 5; // 매장은 최대 5명까지만 동시 입장 가능
this.enteredPersonCount = 0; // 매장에 들어온 손님 수
this.producedCount = 0;
this.waitingList = new LinkedList<>();
}

public int getEnterableCapacity() {
return this.ENTERABLE_CAPACITY;
}

public int getEnteredPersonCount() {
return this.enteredPersonCount;
}

public int getDisplayableCapacity() {
return this.DISPLAYABLE_CAPACITY;
}


public synchronized void enter() { // 매장 입장
try {
System.out.println("enter 메서드에 들어왔습니다 : " + Thread.currentThread().getName());

while (enteredPersonCount == ENTERABLE_CAPACITY) {
System.out.println(Thread.currentThread().getName() + "이 웨이팅 줄에서 사람이 빠지기를 기다립니다 : " + enteredPersonCount + " 명");
waitingList.add(Thread.currentThread());
wait(); // 인원 초과시 나가기를 기다린다.
}

if (waitingList.contains(Thread.currentThread())) {
waitingList.remove(Thread.currentThread());
}

enteredPersonCount++;
System.out.println(Thread.currentThread().getName() + " 입장 했습니다.");
System.out.println("현재 까지 " + enteredPersonCount + " 명 입장해 있습니다.");
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 이 중지됩니다...");
Thread.currentThread().interrupt();
}
}

public synchronized void exit() { // 매장 퇴장
enteredPersonCount--;
if (! waitingList.isEmpty()) {
notifyAll();
}
System.out.println(Thread.currentThread().getName() + " 가 퇴장했습니다.");
}

public synchronized void buy() { // 납품 받기 : 매장에서 물건 납품은 동시에 1명만 가능
try {
while (products.size() == DISPLAYABLE_CAPACITY) {
System.out.println("재고가 꽉 차서 " + Thread.currentThread().getName() + " 이 납품을 한동안 중지합니다 : " + products.size() + " 개");
wait();
}

producedCount++;
Product product = new Product("product" + producedCount, 10000 + producedCount);
products.add(product);
System.out.println("store 에서 " + Thread.currentThread().getName() + " 으로 부터 " + product.getName() + " 를 납품 받았습니다.");
notifyAll(); // 매장에서 물건이 들어오면 소비자에게 알려주기

} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + "이 중지됩니다...");
Thread.currentThread().interrupt();
}
}

public synchronized void sell() { // 판매 : 매장에서 물건 판매도 동시에 1명만 가능
try {
while (products.isEmpty()) { // 비어 있다면
System.out.println("재고가 없어서 납품 받을 때까지 " + Thread.currentThread().getName() + " 가 기다립니다.");
wait(); // 물건이 채워질 때까지 소비자가 Producer 을 기다리기
}
products.remove(0);
System.out.println("store 에서 " + Thread.currentThread().getName() + " 에게 물건을 판매 완료하였습니다.");
notifyAll();
// 매장에서 물건 판매 후 빈 공간이 생기면 생산자에게 알려주기

} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 이 중지됩니다...");
Thread.currentThread().interrupt();
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading