diff --git a/.idea/modules.xml b/.idea/modules.xml index 4510a569..8f06dd04 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,6 +2,12 @@ + + + + + + diff --git a/Assignment/src/main/java/org/example/yunhwa/bankwindow/Desk.java b/Assignment/src/main/java/org/example/yunhwa/bankwindow/Desk.java index e65f5586..b33b4d3a 100644 --- a/Assignment/src/main/java/org/example/yunhwa/bankwindow/Desk.java +++ b/Assignment/src/main/java/org/example/yunhwa/bankwindow/Desk.java @@ -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()); diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Consumer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Consumer.java" new file mode 100644 index 00000000..46c2a863 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Consumer.java" @@ -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; + Store store; + + public Consumer(String name, Store store) { + this.name = name; + this.store = store; + } + + @Override + public void run() { + 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(); // 퇴장 + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Main.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Main.java" new file mode 100644 index 00000000..cef6d15f --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Main.java" @@ -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"); + 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(); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Producer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Producer.java" new file mode 100644 index 00000000..6203da32 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Producer.java" @@ -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(); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Product.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Product.java" new file mode 100644 index 00000000..38ab344e --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Product.java" @@ -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; + } + +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Store.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Store.java" new file mode 100644 index 00000000..977ce16f --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/Store.java" @@ -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 products; + private final int DISPLAYABLE_CAPACITY; + private final int ENTERABLE_CAPACITY; + private int enteredPersonCount; + private int producedCount; + private Queue waitingList; + + 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(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/img.png" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/img.png" new file mode 100644 index 00000000..02a03e2a Binary files /dev/null and "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/img.png" differ diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/\354\203\235\354\202\260\354\236\220-\354\206\214\353\271\204\354\236\220_\354\206\224\353\243\250\354\205\230.md" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/\354\203\235\354\202\260\354\236\220-\354\206\214\353\271\204\354\236\220_\354\206\224\353\243\250\354\205\230.md" new file mode 100644 index 00000000..e04fc71b --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_10_\354\227\260\354\212\265\353\254\270\354\240\234/\354\203\235\354\202\260\354\236\220-\354\206\214\353\271\204\354\236\220_\354\206\224\353\243\250\354\205\230.md" @@ -0,0 +1,97 @@ +생산자 - 소비자 솔루션 +Thread 를 이용해 생산자와 소비자가 거래하는 생산자 - 소비자 솔루션을 구성해본다. + +![img.png](img.png) + + + +Exam- 01. 마트 내에 위치한 매장(Store) 을 정의하라. +- 매장은 물건을 납품 받아서 판매한다. +- 매장에는 최대 10개의 물건만 전시할 수 있다. +- 매장은 최대 5명까지만 동시 입장 가능하다. +- 매장에서 물건 구매는 동시에 1명만 가능하다. +- 매장에서 물건 판매 후 빈 공간이 생기면 생산자에게 알려준다. +- 매장에서 물건 납품은 동시에 1명만 가능하다. +- 매장에서 물건이 들어오면 소비자에게 알려준다. + + + + public class Store { + ... + + public Store() { + ... + } + + public void enter() { + ... + + } + + public void exit() { + ... + } + + public synchronized void buy() { + ... + } + + public synchronized void sell() { + ... + } + } + + +Exam-02. 매장에 물건을 납품하는 생산자(Producer)을 정의하라. +- 생산자는 매장에 물건이 부족하지 않도록 채워둔다. +- 물건은 1~10초 간격으로 채운다. +- Thread내에서 난수 생성을 위해서는 ThreadLocalRandom.current().nextInt()를 사용하면 된다. + + + + import java.util.concurrent.ThreadLocalRandom; + + public class Producer implements Runnable { + ... + + public Producer(Store store) { + ... + } + + @Override + public void run() { + ... + } + } + + + + +Exam-03. 매장에 물건을 구매하는 소비자(Consumer)을 정의하라. +소비자는 매장에 입장 후 물건을 구매할 수 있다. + +매장에는 입장 인원 제한이 있으므로, 인원 초과시 기다린다. + +매장에 입장하면 물건을 구매하고, 퇴장한다. + +1~10초 간격으로 구매한다. + + + + + + import java.util.concurrent.ThreadLocalRandom; + + public class Consumer implements Runnable { + Store store; + ... + + public Consumer(String name, Store store) { + ... + } + + @Override + public void run() { + ... + } + } \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Consumer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Consumer.java" new file mode 100644 index 00000000..6c308e09 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Consumer.java" @@ -0,0 +1,40 @@ +package com.nhnacademy.yunhwa._11_과제; + + +/* + * Exam-03. 매장에 물건을 구매하는 소비자(Consumer)을 정의하라. + * - 소비자는 매장에 입장 후 물건을 구매할 수 있다. + * - 매장에는 입장 인원 제한이 있으므로, 인원 초과시 기다린다. + * - 매장에 입장하면 물건을 구매하고, 퇴장한다. + * - 1~10초 간격으로 구매한다. + * */ + +import java.util.concurrent.ThreadLocalRandom; + +public class Consumer implements Runnable { + String name; + Store store; // 특정 품목의 매장 + + public Consumer(String name, Store store) { + this.name = name; + this.store = store; + } + + @Override + public void run() { + store.enter(); // 매장에 입장 + + // 물건을 1~10초 간격으로 구매 (store 입장에서는 판매) + int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1; + try { + Thread.sleep(randomInterval * 1000); + } catch (InterruptedException e) { + System.out.println("Consumer run() 에서 " + Thread.currentThread().getName() + + " 이 중지됩니다. ----------------------------------\n"); + Thread.currentThread().interrupt(); + } + store.sell(); + + store.exit(); // 퇴장 + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Main.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Main.java" new file mode 100644 index 00000000..0ac1b762 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Main.java" @@ -0,0 +1,54 @@ +package com.nhnacademy.yunhwa._11_과제; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +public class Main { + public static void main(String[] args) throws InterruptedException { + final int STORE_COUNT = 3; + final int CONSUMER_COUNT = 30; + + Mart mart = new Mart(STORE_COUNT); // 매장 3개인 마트 + + Store[] stores = mart.getStores(); // 마트 내의 각 품목별 매장 + + Thread producer = new Thread(new Producer(mart, STORE_COUNT), "producer"); // 생산자 1명 + Thread[] consumers = new Thread[CONSUMER_COUNT]; // 소비자 30명 + + for (int i = 0; i < consumers.length; i++) { + int randomIndex = ThreadLocalRandom.current().nextInt(consumers.length); + consumers[i] = new Thread(new Consumer("consumer" + i, stores[randomIndex % STORE_COUNT]), "consumer" + i); + } + + producer.start(); + + for (int i = 0; i < consumers.length; i++) { + consumers[i].start(); + try { + Thread.sleep(1000 * 2); + } catch (InterruptedException ignore) { + } + } + + try { + Thread.sleep(1000 * 20); + } catch (InterruptedException ignore) { + } + +// producer.interrupt(); +// System.out.println(producer.getName() + " 이 interrupt 되었습니다.\n"); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException ignore) { +// } + +// for(int i = 0; i < consumers.length; i++) { +// consumers[i].interrupt(); +// System.out.println(consumers[i].getName() + " 이 interrupt 되었습니다.\n"); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException ignore) { +// } +// } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Mart.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Mart.java" new file mode 100644 index 00000000..c7af0d1e --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Mart.java" @@ -0,0 +1,18 @@ +package com.nhnacademy.yunhwa._11_과제; + +public class Mart { + Store[] stores; + + public Mart(int storeCount) { // storeCount == n + this.stores = new Store[storeCount]; + + for (int i = 0; i < storeCount; i++) { + stores[i] = new Store("itemType" + i); + } + } + + public Store[] getStores() { + return this.stores; + } + +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Producer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Producer.java" new file mode 100644 index 00000000..5032b368 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Producer.java" @@ -0,0 +1,38 @@ +package com.nhnacademy.yunhwa._11_과제; + +/* +* Exam-02. 매장에 물건을 납품하는 생산자(Producer)을 정의하라. +* - 생산자는 매장에 물건이 부족하지 않도록 채워둔다. +* - 물건은 1~10초 간격으로 채운다. +* - Thread내에서 난수 생성을 위해서는 ThreadLocalRandom.current().nextInt()를 사용하면 된다. +* */ + +import java.util.concurrent.ThreadLocalRandom; + +public class Producer implements Runnable { // 매장에 다양한 물건을 납품하는 생산자(Producer) + private Mart mart; + private int itemTypeCount; // 납품 가능한 품목 종류 + + public Producer(Mart mart, int itemTypeCount) { + this.mart = mart; + this.itemTypeCount = itemTypeCount; + } + + @Override + public void run() { + while (! Thread.currentThread().isInterrupted()) { + try { + int randomIndex = ThreadLocalRandom.current().nextInt(itemTypeCount); + mart.stores[randomIndex].buy(); + + System.out.println("(" + Thread.currentThread().getName() + ") 가 물건 납품을 완료하고 돌아왔습니다.\n"); + int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1; + Thread.sleep(randomInterval * 100); + + } catch (InterruptedException e) { + System.out.println("Producer run() 에서 " + Thread.currentThread().getName() + " 이 중지됩니다. ----------------------------------\n"); + Thread.currentThread().interrupt(); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Product.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Product.java" new file mode 100644 index 00000000..62292c78 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Product.java" @@ -0,0 +1,20 @@ +package com.nhnacademy.yunhwa._11_과제; + +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; + } + +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Store.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Store.java" new file mode 100644 index 00000000..c173bdc2 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/Store.java" @@ -0,0 +1,128 @@ +package com.nhnacademy.yunhwa._11_과제; + +/* + * 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 String itemTypeName; // 해당 매장에서 취급하는 품목 이름 + private List products; + private final int DISPLAYABLE_CAPACITY; + private final int ENTERABLE_CAPACITY; + private int enteredPersonCount; + private int producedCount; + private Queue waitingList; + + public Store(String itemTypeName) { + this.itemTypeName = itemTypeName; // 품목 이름 파라미터 받아서 할당 + 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("[" + itemTypeName + "] store 으로 <" + Thread.currentThread().getName() + "> 님이 입장 예정입니다."); + + while (enteredPersonCount == ENTERABLE_CAPACITY) { + if (! waitingList.contains(Thread.currentThread().getName())) { + waitingList.add(Thread.currentThread().getName()); + System.out.println("[" + itemTypeName + "] store 으로 들어가기 위해 <<" + Thread.currentThread().getName() + ">> 님이 웨이팅 줄에서 사람이 빠지기를 기다립니다 / 대기줄 명수: " + this.waitingList.size() + " / 현재 매장에 들어가있는 고객 수 : " + enteredPersonCount + " 명"); + } + wait(); // 인원 초과시 나가기를 기다린다. + } + + if (waitingList.contains(Thread.currentThread().getName())) { + + System.out.println("[" + itemTypeName + "] store 의 대기줄에서 기다리던 고객이 들어갈 차례! 대기줄에서 빠지기 전 대기줄 명수 : " + waitingList.size()); + System.out.println("(귓속말) <<" + Thread.currentThread().getName() + ">> 님은 여태 [" + itemTypeName + "] store 의 대기줄에 있다 들어갈 고객입니다. 신경써서 판매 부탁드립니다."); + waitingList.remove(Thread.currentThread().getName()); + System.out.println("[" + itemTypeName + "] store 의 대기줄에서 기다리던 고객이 들어갈 차례! 대기줄에서 빠진 후 대기줄 명수 : " + waitingList.size()); + } + + enteredPersonCount++; + System.out.println("-> " + "[" + itemTypeName + "] store 으로 <" + Thread.currentThread().getName() + "> 님 입장 했습니다."); + System.out.println("==== [" + itemTypeName + "] store" + " 에 현재 까지 " + enteredPersonCount + " 명 입장해 있습니다. ===="); + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님이 중지됩니다... ---------------------------------- Store enter() 메서드"); + Thread.currentThread().interrupt(); + } + } + + public synchronized void exit() { // 매장 퇴장 + enteredPersonCount--; + System.out.println("<- " + "[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님이 퇴장했습니다."); + if (! waitingList.isEmpty()) { + notifyAll(); + } + } + + public synchronized void buy() { // 납품 받기 : 매장에서 물건 납품은 동시에 1명만 가능 - 생산자 + try { + boolean isStillWait = false; + while (products.size() == DISPLAYABLE_CAPACITY) { + if (! isStillWait) { + isStillWait = true; + System.out.println("[" + itemTypeName + "] store 의 재고가 꽉 차서 (" + Thread.currentThread().getName() + ") 이 납품을 한동안 중지합니다. / 현재 [" + itemTypeName + "] store 재고량 : " + products.size() + " 개"); + } + wait(); + } + + producedCount++; + Product product = new Product("product" + producedCount, 10000 + producedCount); + products.add(product); + + System.out.println("[" + itemTypeName + "] store 에서 (" + Thread.currentThread().getName() + ") 으로 부터 |" + product.getName() + "| 를 납품 받았습니다. 현재 [" + itemTypeName + "] store 재고량 : " + products.size() + " 개"); + notifyAll(); // 매장에서 물건이 들어오면 소비자에게 알려주기 + + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 (" + Thread.currentThread().getName() + ") 이 중지됩니다... ---------------------------------- Store buy() 메서드"); + Thread.currentThread().interrupt(); + } + } + + public synchronized void sell() { // 판매 : 매장에서 물건 판매도 동시에 1명만 가능 + try { + while (products.isEmpty()) { // 비어 있다면 + System.out.println("[" + itemTypeName + "] store 에 " + "재고가 없어서 납품 받을 때까지 <" + Thread.currentThread().getName() + "> 가 기다립니다."); + wait(); // 물건이 채워질 때까지 소비자가 Producer 을 기다리기 + } + products.remove(0); + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님에게 물건을 판매 완료하였습니다."); + notifyAll(); + // 매장에서 물건 판매 후 빈 공간이 생기면 생산자에게 알려주기 + + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 이 중지됩니다... ---------------------------------- Store sell() 메서드"); + Thread.currentThread().interrupt(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Consumer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Consumer.java" new file mode 100644 index 00000000..f1ca1271 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Consumer.java" @@ -0,0 +1,39 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +/* + * Exam-03. 매장에 물건을 구매하는 소비자(Consumer)을 정의하라. + * - 소비자는 매장에 입장 후 물건을 구매할 수 있다. + * - 매장에는 입장 인원 제한이 있으므로, 인원 초과시 기다린다. + * - 매장에 입장하면 물건을 구매하고, 퇴장한다. + * - 1~10초 간격으로 구매한다. + * */ + +import java.util.concurrent.ThreadLocalRandom; + +public class Consumer implements Runnable { + String name; + Store store; // 특정 품목의 매장 + + public Consumer(String name, Store store) { + this.name = name; + this.store = store; + } + + @Override + public void run() { + store.enter(); // 매장에 입장 + + // 물건을 1~10초 간격으로 구매 (store 입장에서는 판매) + int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1; + try { + Thread.sleep(randomInterval * 1000); + } catch (InterruptedException e) { + System.out.println("Consumer run() 에서 " + Thread.currentThread().getName() + + " 이 중지됩니다. ----------------------------------\n"); + Thread.currentThread().interrupt(); + } + store.sell(); + + store.exit(); // 퇴장 + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Main.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Main.java" new file mode 100644 index 00000000..d2de73ff --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Main.java" @@ -0,0 +1,53 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +import java.util.concurrent.ThreadLocalRandom; + +public class Main { + public static void main(String[] args) throws InterruptedException { + final int STORE_COUNT = 3; + final int CONSUMER_COUNT = 30; + + Mart mart = new Mart(STORE_COUNT); // 매장 3개인 마트 + + Store[] stores = mart.getStores(); // 마트 내의 각 품목별 매장 + + Thread producer = new Thread(new Producer(mart, STORE_COUNT), "producer"); // 생산자 1명 + Thread[] consumers = new Thread[CONSUMER_COUNT]; // 소비자 30명 + + for (int i = 0; i < consumers.length; i++) { + int randomIndex = ThreadLocalRandom.current().nextInt(consumers.length); + consumers[i] = new Thread(new Consumer("consumer" + i, stores[randomIndex % STORE_COUNT]), "consumer" + i); + } + + producer.start(); + + for (int i = 0; i < consumers.length; i++) { + consumers[i].start(); + try { + Thread.sleep(1000 * 2); + } catch (InterruptedException ignore) { + } + } + + try { + Thread.sleep(1000 * 20); + } catch (InterruptedException ignore) { + } + +// producer.interrupt(); +// System.out.println(producer.getName() + " 이 interrupt 되었습니다.\n"); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException ignore) { +// } + +// for(int i = 0; i < consumers.length; i++) { +// consumers[i].interrupt(); +// System.out.println(consumers[i].getName() + " 이 interrupt 되었습니다.\n"); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException ignore) { +// } +// } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Mart.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Mart.java" new file mode 100644 index 00000000..2a963262 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Mart.java" @@ -0,0 +1,18 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +public class Mart { + Store[] stores; + + public Mart(int storeCount) { // storeCount == n + this.stores = new Store[storeCount]; + + for (int i = 0; i < storeCount; i++) { + stores[i] = new Store("itemType" + i); + } + } + + public Store[] getStores() { + return this.stores; + } + +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Producer.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Producer.java" new file mode 100644 index 00000000..870113ad --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Producer.java" @@ -0,0 +1,38 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +/* +* Exam-02. 매장에 물건을 납품하는 생산자(Producer)을 정의하라. +* - 생산자는 매장에 물건이 부족하지 않도록 채워둔다. +* - 물건은 1~10초 간격으로 채운다. +* - Thread내에서 난수 생성을 위해서는 ThreadLocalRandom.current().nextInt()를 사용하면 된다. +* */ + +import java.util.concurrent.ThreadLocalRandom; + +public class Producer implements Runnable { // 매장에 다양한 물건을 납품하는 생산자(Producer) + private Mart mart; + private int itemTypeCount; // 납품 가능한 품목 종류 + + public Producer(Mart mart, int itemTypeCount) { + this.mart = mart; + this.itemTypeCount = itemTypeCount; + } + + @Override + public void run() { + while (! Thread.currentThread().isInterrupted()) { + try { + int randomIndex = ThreadLocalRandom.current().nextInt(itemTypeCount); + mart.stores[randomIndex].buy(); + + System.out.println("(" + Thread.currentThread().getName() + ") 가 물건 납품을 완료하고 돌아왔습니다.\n"); + int randomInterval = ThreadLocalRandom.current().nextInt(10) + 1; + Thread.sleep(randomInterval * 100); + + } catch (InterruptedException e) { + System.out.println("Producer run() 에서 " + Thread.currentThread().getName() + " 이 중지됩니다. ----------------------------------\n"); + Thread.currentThread().interrupt(); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Product.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Product.java" new file mode 100644 index 00000000..c31fe59e --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Product.java" @@ -0,0 +1,20 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +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; + } + +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Store.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Store.java" new file mode 100644 index 00000000..6363831b --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_11_\352\263\274\354\240\234/semaphore/Store.java" @@ -0,0 +1,129 @@ +package com.nhnacademy.yunhwa._11_과제.semaphore; + +/* + * 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 String itemTypeName; // 해당 매장에서 취급하는 품목 이름 + private List products; + private final int DISPLAYABLE_CAPACITY; + private final int ENTERABLE_CAPACITY; + private int enteredPersonCount; + private int producedCount; + private Queue waitingList; + + public Store(String itemTypeName) { + this.itemTypeName = itemTypeName; // 품목 이름 파라미터 받아서 할당 + 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("[" + itemTypeName + "] store 으로 <" + Thread.currentThread().getName() + "> 님이 입장 예정입니다."); + + while (enteredPersonCount == ENTERABLE_CAPACITY) { + if (! waitingList.contains(Thread.currentThread().getName())) { + waitingList.add(Thread.currentThread().getName()); + System.out.println("[" + itemTypeName + "] store 으로 들어가기 위해 <<" + Thread.currentThread().getName() + ">> 님이 웨이팅 줄에서 사람이 빠지기를 기다립니다 / 대기줄 명수: " + this.waitingList.size() + " / 현재 매장에 들어가있는 고객 수 : " + enteredPersonCount + " 명"); + } + wait(); // 인원 초과시 나가기를 기다린다. + } + + if (waitingList.contains(Thread.currentThread().getName())) { + + System.out.println("[" + itemTypeName + "] store 의 대기줄에서 기다리던 고객이 들어갈 차례! 대기줄에서 빠지기 전 대기줄 명수 : " + waitingList.size()); + System.out.println("(귓속말) <<" + Thread.currentThread().getName() + ">> 님은 여태 [" + itemTypeName + "] store 의 대기줄에 있다 들어갈 고객입니다. 신경써서 판매 부탁드립니다."); + waitingList.remove(Thread.currentThread().getName()); + System.out.println("[" + itemTypeName + "] store 의 대기줄에서 기다리던 고객이 들어갈 차례! 대기줄에서 빠진 후 대기줄 명수 : " + waitingList.size()); + } + + enteredPersonCount++; + System.out.println("-> " + "[" + itemTypeName + "] store 으로 <" + Thread.currentThread().getName() + "> 님 입장 했습니다."); + System.out.println("==== [" + itemTypeName + "] store" + " 에 현재 까지 " + enteredPersonCount + " 명 입장해 있습니다. ===="); + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님이 중지됩니다... ---------------------------------- Store enter() 메서드"); + Thread.currentThread().interrupt(); + } + } + + public synchronized void exit() { // 매장 퇴장 + enteredPersonCount--; + System.out.println("<- " + "[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님이 퇴장했습니다."); + if (! waitingList.isEmpty()) { + notifyAll(); + } + } + + public synchronized void buy() { // 납품 받기 : 매장에서 물건 납품은 동시에 1명만 가능 - 생산자 + try { + boolean isStillWait = false; + while (products.size() == DISPLAYABLE_CAPACITY) { + if (! isStillWait) { + isStillWait = true; + System.out.println("[" + itemTypeName + "] store 의 재고가 꽉 차서 (" + Thread.currentThread().getName() + ") 이 납품을 한동안 중지합니다. / 현재 [" + itemTypeName + "] store 재고량 : " + products.size() + " 개"); + } + wait(); + } + + producedCount++; + Product + product = new Product("product" + producedCount, 10000 + producedCount); + products.add(product); + + System.out.println("[" + itemTypeName + "] store 에서 (" + Thread.currentThread().getName() + ") 으로 부터 |" + product.getName() + "| 를 납품 받았습니다. 현재 [" + itemTypeName + "] store 재고량 : " + products.size() + " 개"); + notifyAll(); // 매장에서 물건이 들어오면 소비자에게 알려주기 + + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 (" + Thread.currentThread().getName() + ") 이 중지됩니다... ---------------------------------- Store buy() 메서드"); + Thread.currentThread().interrupt(); + } + } + + public synchronized void sell() { // 판매 : 매장에서 물건 판매도 동시에 1명만 가능 + try { + while (products.isEmpty()) { // 비어 있다면 + System.out.println("[" + itemTypeName + "] store 에 " + "재고가 없어서 납품 받을 때까지 <" + Thread.currentThread().getName() + "> 가 기다립니다."); + wait(); // 물건이 채워질 때까지 소비자가 Producer 을 기다리기 + } + products.remove(0); + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 님에게 물건을 판매 완료하였습니다."); + notifyAll(); + // 매장에서 물건 판매 후 빈 공간이 생기면 생산자에게 알려주기 + + } catch (InterruptedException e) { + System.out.println("[" + itemTypeName + "] store 에서 <" + Thread.currentThread().getName() + "> 이 중지됩니다... ---------------------------------- Store sell() 메서드"); + Thread.currentThread().interrupt(); + } + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Counter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Counter.java new file mode 100644 index 00000000..bde14b65 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Counter.java @@ -0,0 +1,30 @@ +package com.nhnacademy.yunhwa._1_thread_class; + +public class Counter { + private int count; + private final String name; + private final int maxCount; + + public Counter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + } + + /* + * 시작 후 1초마다 횟수를 1씩 증가 시킨다. + * 횟수가 변경될 때마다 이름과 횟수를 출력한다. + * 주어진 최대 횟수에 도달하면, 동작을 종료한다. + * */ + public void run() { // Thread 클래스에서 실행 코드는 run() 에 정의되어야 한다. + while (count < this.maxCount) { + try { + Thread.sleep(1000); + count++; + System.out.println(this.name + "'s count : " + count); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } // run() +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Main.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Main.java new file mode 100644 index 00000000..d82ff9f7 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/Main.java @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._1_thread_class; + +public class Main { + public static void main(String[] args) { + // main 쓰레드에서 순차적으로 적용 +// Counter counter1 = new Counter("counter1", 10); +// Counter counter2 = new Counter("counter2", 10); +// counter1.run(); +// counter2.run(); + +// ThreadCounter threadCounter1 = new ThreadCounter("threadCounter1", 10); +// ThreadCounter threadCounter2 = new ThreadCounter("threadCounter2", 10); +// threadCounter1.run(); +// threadCounter2.run(); + + // 별도의 쓰레드에서 수행하도록 만들기 + ThreadCounter threadCounter3 = new ThreadCounter("threadCounter3", 10); + ThreadCounter threadCounter4 = new ThreadCounter("threadCounter4", 10); + threadCounter3.start(); + threadCounter4.start(); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/ThreadCounter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/ThreadCounter.java new file mode 100644 index 00000000..91927500 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_1_thread_class/ThreadCounter.java @@ -0,0 +1,31 @@ +package com.nhnacademy.yunhwa._1_thread_class; + +public class ThreadCounter extends Thread { + private int count; + private String name; + private final int maxCount; + + public ThreadCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + } + + /* + * 시작 후 1초마다 횟수를 1씩 증가 시킨다. + * 횟수가 변경될 때마다 이름과 횟수를 출력한다. + * 주어진 최대 횟수에 도달하면, 동작을 종료한다. + * */ + @Override + public void run() { // Thread 클래스에서 실행 코드는 run() 에 정의되어야 한다. + while (count < this.maxCount) { + try { + Thread.sleep(1000); + count++; + System.out.println(this.name + "'s count : " + count); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } // run() +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam01/Exam01.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam01/Exam01.java new file mode 100644 index 00000000..257b64eb --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam01/Exam01.java @@ -0,0 +1,14 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.exam01; + +import com.nhnacademy.yunhwa._2_runnable_interface.quiz01.RunnableCounter; + +public class Exam01 { + public static void main(String[] args) throws InterruptedException { + RunnableCounter runnableCounter = new RunnableCounter("counter", 5); + Thread thread = new Thread(runnableCounter); + + thread.start(); + thread.join(); + System.out.println("main 이 종료되었습니다."); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/Exam02.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/Exam02.java new file mode 100644 index 00000000..66b64f72 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/Exam02.java @@ -0,0 +1,9 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.exam02; + +public class Exam02 { + public static void main(String[] args) { + SelfRunnableCounter selfRunnableCounter = new SelfRunnableCounter("counter", 5); + + selfRunnableCounter.start(); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/SelfRunnableCounter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/SelfRunnableCounter.java new file mode 100644 index 00000000..e659294a --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam02/SelfRunnableCounter.java @@ -0,0 +1,30 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.exam02; + +public class SelfRunnableCounter implements Runnable { + private int count; + private int maxCount; + private Thread thread; // thread 필드 추가 + + public SelfRunnableCounter(String name, int maxCount) { + this.maxCount = maxCount; + this.count = 0; + this.thread = new Thread(this, name); // constructor 에서 thread instance 를 생성하고, 인자로 자신을 넘긴다. + } + + public void start() { + thread.start(); + } + + @Override + public void run() { + while (this.count < this.maxCount) { + try { + this.count++; + System.out.println(this.thread.getName() + "'s count : " + this.count); + Thread.sleep(1000); + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } + } + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam03/Exam03.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam03/Exam03.java new file mode 100644 index 00000000..b3f6242b --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/exam03/Exam03.java @@ -0,0 +1,21 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.exam03; + +import com.nhnacademy.yunhwa._2_runnable_interface.quiz01.RunnableCounter; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class Exam03 { + public static void main(String[] args) throws InterruptedException { + ExecutorService pool = Executors.newFixedThreadPool(1); // ExecutorService 를 이용해 thread pool 을 생성한다. 이때, pool의 크기는 1로 한다. + pool.execute(new RunnableCounter("counter1", 5)); // Thread pool 에 RunnableCounter instance 를 생성해 넘기고 실행하도록 한다. + pool.execute(new RunnableCounter("counter2", 5)); + + pool.shutdown(); + System.out.println("Shutdown called"); + while (! pool.awaitTermination(2, TimeUnit.SECONDS)) { + System.out.println("Not yet finished"); + } + System.out.println("All service finished"); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/Main.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/Main.java new file mode 100644 index 00000000..0936494d --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/Main.java @@ -0,0 +1,9 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.quiz01; + +public class Main { + public static void main(String[] args) { + RunnableCounter runnableCounter = new RunnableCounter("runnableCounter", 10); + Thread thread = new Thread(runnableCounter); + thread.start(); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/RunnableCounter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/RunnableCounter.java new file mode 100644 index 00000000..daba6c8d --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_2_runnable_interface/quiz01/RunnableCounter.java @@ -0,0 +1,27 @@ +package com.nhnacademy.yunhwa._2_runnable_interface.quiz01; + +public class RunnableCounter implements Runnable { + + private String name; + private int count; + private int maxCount; + + public RunnableCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + } + + @Override + public void run() { + while (this.count < this.maxCount) { + try { + Thread.sleep(1000); + this.count++; + System.out.println(this.name + "'s count : " + this.count); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/Quiz01.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/Quiz01.java" new file mode 100644 index 00000000..db56f7d5 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/Quiz01.java" @@ -0,0 +1,11 @@ +package com.nhnacademy.yunhwa._5_thread_멈추기.quiz01; + +public class Quiz01 { + public static void main(String[] args) throws InterruptedException { + RunnableCounter runnableCounter = new RunnableCounter("counter", 5); + Thread thread = new Thread(runnableCounter); + thread.start(); + Thread.sleep(3000); + runnableCounter.stop(); + } +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/RunnableCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/RunnableCounter.java" new file mode 100644 index 00000000..329d41cd --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz01/RunnableCounter.java" @@ -0,0 +1,39 @@ +package com.nhnacademy.yunhwa._5_thread_멈추기.quiz01; + +public class RunnableCounter implements Runnable { + + private String name; + private int count; + private int maxCount; + private boolean runningFlag; + + public RunnableCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + this.runningFlag = false; + } + + public void stop() { + this.runningFlag = false; + } + + @Override + public void run() { + this.runningFlag = true; + + while (this.count < this.maxCount) { + if (this.runningFlag) { + try { + this.count++; + System.out.println(this.name + "'s count : " + this.count); + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } else { + break; + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/Quiz02.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/Quiz02.java" new file mode 100644 index 00000000..57cf791b --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/Quiz02.java" @@ -0,0 +1,11 @@ +package com.nhnacademy.yunhwa._5_thread_멈추기.quiz02; + +public class Quiz02 { + public static void main(String[] args) throws InterruptedException { + RunnableCounter runnableCounter = new RunnableCounter("counter", 5); + Thread thread = new Thread(runnableCounter); + thread.start(); + Thread.sleep(3000); + thread.interrupt(); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/RunnableCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/RunnableCounter.java" new file mode 100644 index 00000000..cea4bd78 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_5_thread_\353\251\210\354\266\224\352\270\260/quiz02/RunnableCounter.java" @@ -0,0 +1,34 @@ +package com.nhnacademy.yunhwa._5_thread_멈추기.quiz02; + +public class RunnableCounter implements Runnable { + + private String name; + private int count; + private int maxCount; + + + public RunnableCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + } + + + @Override + public void run() { + while (this.count < this.maxCount) { + try { + if (Thread.currentThread().isInterrupted()) { + System.out.println("isinterrupted 가 참입니다. while 문 빠져나옵니다."); + break; + } + this.count++; + System.out.println(this.name + "'s count : " + this.count); + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("interrupt 메서드 호출하여 setting 하였습니다."); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/Exam01.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/Exam01.java" new file mode 100644 index 00000000..c52649e7 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/Exam01.java" @@ -0,0 +1,23 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam01; + +public class Exam01 { + public static void main(String[] args) throws InterruptedException { + SharedCount sharedCount = new SharedCount(); + SharedCounter counter1 = new SharedCounter("counter1", 10000, sharedCount); + SharedCounter counter2 = new SharedCounter("counter2", 10000, sharedCount); + + counter1.start(); + counter2.start(); + + System.out.println(counter1.getName() + ": started"); + System.out.println(counter2.getName() + ": started"); + + counter1.join(); + counter2.join(); + + System.out.println(counter1.getName() + ": terminated"); + System.out.println(counter2.getName() + ": terminated"); + + System.out.println("sharedCount : " + sharedCount.getCount()); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCount.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCount.java" new file mode 100644 index 00000000..cad7e25f --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCount.java" @@ -0,0 +1,17 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam01; + +public class SharedCount { + private int count; + + public int getCount() { + return this.count; + } + + public void setCount(int count) { + this.count = count; + } + + public void increment() { + setCount(getCount() + 1); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCounter.java" new file mode 100644 index 00000000..3105ebb3 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam01/SharedCounter.java" @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam01; + +public class SharedCounter extends Thread { + private final SharedCount sharedCount; + private int count; + private final int maxCount; + + public SharedCounter(String name, int maxCount, SharedCount sharedCount) { + super.setName(name); + this.maxCount = maxCount; + this.sharedCount = sharedCount; + this.count = 0; + } + + @Override + public void run() { + while(count < maxCount) { + count++; + sharedCount.increment(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/Exam02.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/Exam02.java" new file mode 100644 index 00000000..f3808fb4 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/Exam02.java" @@ -0,0 +1,23 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam02; + +public class Exam02 { + public static void main(String[] args) throws InterruptedException { + SharedCount sharedCount = new SharedCount(); + SharedCounter counter1 = new SharedCounter("counter1", 10000, sharedCount); + SharedCounter counter2 = new SharedCounter("counter2", 10000, sharedCount); + + counter1.start(); + counter2.start(); + + System.out.println(counter1.getName() + ": started"); + System.out.println(counter2.getName() + ": started"); + + counter1.join(); + counter2.join(); + + System.out.println(counter1.getName() + ": terminated"); + System.out.println(counter2.getName() + ": terminated"); + + System.out.println("sharedCount : " + sharedCount.getCount()); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCount.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCount.java" new file mode 100644 index 00000000..b62390f6 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCount.java" @@ -0,0 +1,17 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam02; + +public class SharedCount { + private int count; + + public int getCount() { + return this.count; + } + + public void setCount(int count) { + this.count = count; + } + + public synchronized void increment() { + setCount(getCount() + 1); + } +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCounter.java" new file mode 100644 index 00000000..8acd358a --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam02/SharedCounter.java" @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam02; + +public class SharedCounter extends Thread { + private final SharedCount sharedCount; + private int count; + private final int maxCount; + + public SharedCounter(String name, int maxCount, SharedCount sharedCount) { + super.setName(name); + this.maxCount = maxCount; + this.sharedCount = sharedCount; + this.count = 0; + } + + @Override + public void run() { + while(count < maxCount) { + count++; + sharedCount.increment(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/Exam03.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/Exam03.java" new file mode 100644 index 00000000..2349711a --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/Exam03.java" @@ -0,0 +1,25 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam03; + +public class Exam03 { + public static void main(String[] args) throws InterruptedException { + SharedCount sharedCount = new SharedCount(); + SharedCounter + counter1 = new SharedCounter("counter1", 10000, sharedCount); + SharedCounter + counter2 = new SharedCounter("counter2", 10000, sharedCount); + + counter1.start(); + counter2.start(); + + System.out.println(counter1.getName() + ": started"); + System.out.println(counter2.getName() + ": started"); + + counter1.join(); + counter2.join(); + + System.out.println(counter1.getName() + ": terminated"); + System.out.println(counter2.getName() + ": terminated"); + + System.out.println("sharedCount : " + SharedCount.getCount()); + } +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCount.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCount.java" new file mode 100644 index 00000000..c86e6bdf --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCount.java" @@ -0,0 +1,13 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam03; + +public class SharedCount { + private static int count; // shared count 를 static variable 로 선언하여 instance 와 관계 없이 접근 가능하게 만듦. + + public static int getCount() { + return count; + } + + public static synchronized void increment() { + count++; // shared count 를 수정할 수 있도록 increment() 도 static method 로 정의. + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCounter.java" new file mode 100644 index 00000000..c442ee8d --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam03/SharedCounter.java" @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam03; + +public class SharedCounter extends Thread { + private final SharedCount sharedCount; + private int count; + private final int maxCount; + + public SharedCounter(String name, int maxCount, SharedCount sharedCount) { + super.setName(name); + this.maxCount = maxCount; + this.sharedCount = sharedCount; + this.count = 0; + } + + @Override + public void run() { + while(count < maxCount) { + count++; + sharedCount.increment(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/Exam04.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/Exam04.java" new file mode 100644 index 00000000..cd40ff75 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/Exam04.java" @@ -0,0 +1,25 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam04; + +public class Exam04 { + public static void main(String[] args) throws InterruptedException { + SharedCount sharedCount = new SharedCount(); + SharedCounter + counter1 = new SharedCounter("counter1", 10000, sharedCount); + SharedCounter + counter2 = new SharedCounter("counter2", 10000, sharedCount); + + counter1.start(); + counter2.start(); + + System.out.println(counter1.getName() + ": started"); + System.out.println(counter2.getName() + ": started"); + + counter1.join(); + counter2.join(); + + System.out.println(counter1.getName() + ": terminated"); + System.out.println(counter2.getName() + ": terminated"); + + System.out.println("sharedCount : " + sharedCount.getCount()); + } +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCount.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCount.java" new file mode 100644 index 00000000..3324f7a3 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCount.java" @@ -0,0 +1,18 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam04; + +public class SharedCount { + private int count; + + public int getCount() { + return this.count; + } + + public void setCount(int count) { + this.count = count; + } + public void increment() { + synchronized (this) { + setCount(getCount() + 1); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCounter.java" new file mode 100644 index 00000000..44e903fe --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam04/SharedCounter.java" @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam04; + +public class SharedCounter extends Thread { + private final SharedCount sharedCount; + private int count; + private final int maxCount; + + public SharedCounter(String name, int maxCount, SharedCount sharedCount) { + super.setName(name); + this.maxCount = maxCount; + this.sharedCount = sharedCount; + this.count = 0; + } + + @Override + public void run() { + while(count < maxCount) { + count++; + sharedCount.increment(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Data.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Data.java" new file mode 100644 index 00000000..77c0074d --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Data.java" @@ -0,0 +1,47 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam05; + +public class Data { + private String packet; + + // 참이면 sender가 아직 데이터를 안보낸 것. 이동을 아직 안한 것. + private boolean notTransfer = true; // True if receiver should wait // False if sender should wait + + public synchronized void send(String packet) { // 보낸다 + while (!notTransfer) { // 전송이 완료된 상태라면 + try { + wait(); // sender 가 waiting 상태에 들어간다. receiver 가 데이터를 받을 때까지 대기 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Thread Interrupted"); + } + } // wait 가 다 끝났으면. + notTransfer = false; // 전송이 다 되었다고 초기화시킴. + + this.packet = packet; + notifyAll(); // receiver 에게 전송 완료를 알림 + } + + public synchronized String receive() { // 받는다 + while (notTransfer) { // 전송이 완료되지 않은 상태라면 + try { + wait(); // receiver 이 waiting 상태에 들어간다. sender 가 데이터를 보낼 때까지 대기 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Thread Interrupted"); + } + } // 전송 완료됨. + notTransfer = true; // 한 턴이 끝났으니, 다음을 위해 전송 아직 완료되지 않았다고 초기화 시킴. + + String returnPacket = packet; + notifyAll(); // sender 에게 수신 완료를 알림. + + return returnPacket; + } + + + + + + + +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Exam05.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Exam05.java" new file mode 100644 index 00000000..9a889dd7 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Exam05.java" @@ -0,0 +1,12 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam05; + +public class Exam05 { + public static void main(String[] args) { + Data data = new Data(); + Thread sender = new Thread(new Sender(data)); + Thread receiver = new Thread(new Receiver(data)); + + sender.start(); + receiver.start(); + } +} \ No newline at end of file diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Receiver.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Receiver.java" new file mode 100644 index 00000000..0ca14e60 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Receiver.java" @@ -0,0 +1,26 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam05; + +import java.util.concurrent.ThreadLocalRandom; + +public class Receiver implements Runnable { + Data data; + + public Receiver(Data data) { + this.data = data; + } + + @Override + public void run() { + for (String receivedMessage = data.receive(); !"End".equals(receivedMessage); receivedMessage = data.receive()) { + + System.out.println(receivedMessage); + + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Thread Interrupted"); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Sender.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Sender.java" new file mode 100644 index 00000000..9eae6157 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_6_thread_\353\217\231\352\270\260\355\231\224/exam05/Sender.java" @@ -0,0 +1,34 @@ +package com.nhnacademy.yunhwa._6_thread_동기화.exam05; + +import java.util.concurrent.ThreadLocalRandom; + +public class Sender implements Runnable { + Data data; + + public Sender(Data data) { + this.data = data; + } + + @Override + public void run() { + String packets[] = { + "First packet", + "Second packet", + "Third packet", + "Fourth packet", + "End" + }; + + for (String packet : packets) { + data.send(packet); + + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000, 5000)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.err.println("Thread Interrupted"); + } + } + + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam01/Exam01.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam01/Exam01.java" new file mode 100644 index 00000000..b9a9f60d --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam01/Exam01.java" @@ -0,0 +1,8 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam01; + +public class Exam01 { + public static void main(String[] args) { + Thread thread = new Thread(); + System.out.println(thread.getState()); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/Exam02.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/Exam02.java" new file mode 100644 index 00000000..5ddc6467 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/Exam02.java" @@ -0,0 +1,12 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam02; + + + +public class Exam02 { + public static void main(String[] args) { + RunnableCounter runnableCounter = new RunnableCounter("counter", 5); + runnableCounter.start(); + + System.out.println(runnableCounter.getThread().getState()); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/RunnableCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/RunnableCounter.java" new file mode 100644 index 00000000..8ea2f815 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam02/RunnableCounter.java" @@ -0,0 +1,43 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam02; + +public class RunnableCounter implements Runnable { + + private String name; + private int count; + private int maxCount; + private Thread thread; + + public RunnableCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + this.thread = new Thread(this, name); + } + + public Thread getThread() { + return this.thread; + } + + + public void start() { + this.thread.start(); + } + + @Override + public void run() { + while (this.count < this.maxCount) { + try { + if (Thread.currentThread().isInterrupted()) { + System.out.println("isinterrupted 가 참입니다. while 문 빠져나옵니다."); + break; + } + this.count++; + System.out.println(this.name + "'s count : " + this.count); + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("interrupt 메서드 호출하여 setting 하였습니다."); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/Exam03.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/Exam03.java" new file mode 100644 index 00000000..4df0b3eb --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/Exam03.java" @@ -0,0 +1,27 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam03; + + +public class Exam03 { + public static void main(String[] args) throws InterruptedException { + SharedCount sharedCount = new SharedCount(); + SharedCounter counter1 = new SharedCounter("counter1", 5, sharedCount); + SharedCounter counter2 = new SharedCounter("counter2", 5, sharedCount); + + counter1.start(); + counter2.start(); + + Thread.State state1 = counter1.getState(); + Thread.State state2 = counter2.getState(); + System.out.println("T1 : " + state1 + ", T2 : " + state2); + + while (counter1.isAlive() || counter2.isAlive()) { + if ((counter1.getState() != state1) || + (counter2.getState() != state2)) { + state1 = counter1.getState(); + state2 = counter2.getState(); + System.out.println("T1 : " + state1 + ", T2 : " + state2); + } + Thread.sleep(10); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCount.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCount.java" new file mode 100644 index 00000000..f15231c4 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCount.java" @@ -0,0 +1,17 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam03; + +public class SharedCount { + private int count = 0; + + public int getCount() { + return this.count; + } + + public synchronized void increment() { // 공유 자원인 count 를 변경 시 하나의 Thread 만 접근 가능하도록 처리 + count++; + try { + Thread.sleep(100); + } catch (InterruptedException ignore) { + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCounter.java" new file mode 100644 index 00000000..6a77e82b --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam03/SharedCounter.java" @@ -0,0 +1,28 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam03; + +public class SharedCounter extends Thread { + private final SharedCount sharedCount; + private int count; + private final int maxCount; + private long interval = 1000; + + public SharedCounter(String name, int maxCount, SharedCount sharedCount) { + super.setName(name); + this.maxCount = maxCount; + this.sharedCount = sharedCount; + this.count = 0; + } + + @Override + public void run() { + while (count < maxCount) { + try { + count++; + sharedCount.increment(); + Thread.sleep(interval); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/Exam04.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/Exam04.java" new file mode 100644 index 00000000..4913b386 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/Exam04.java" @@ -0,0 +1,24 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam04; + + +public class Exam04 { + public static void main(String[] args) { + // thread class 를 이용해 1초에 1씩 증가하여 10까지 증가하는 counter object 를 생성한다. + RunnableCounter counter = new RunnableCounter("counter", 10); + + WaitingCounter waitingCounter = new WaitingCounter(counter); + + counter.start(); + waitingCounter.start(); + + Thread.State state = waitingCounter.getThread().getState(); + System.out.println(state); + + while (waitingCounter.isAlive()) { + if (state != waitingCounter.getThread().getState()) { + state = waitingCounter.getThread().getState(); + System.out.println(state); + } + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/RunnableCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/RunnableCounter.java" new file mode 100644 index 00000000..de6664d7 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/RunnableCounter.java" @@ -0,0 +1,55 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam04; + +public class RunnableCounter implements Runnable { + private Thread thread; + private int count = 0; + private int maxCount; + private long interval = 1000; + + + public RunnableCounter(String name, int maxCount) { + this.maxCount = maxCount; + this.thread = new Thread(this, name); + } + + public int getCount() { + return this.count; + } + + public void increment() { + this.count++; + } + + public int getMaxCount() { + return this.maxCount; + } + + public void start() { + this.thread.start(); + } + + public void stop() { + this.thread.interrupt(); + } + + public Thread getThread() { + return this.thread; + } + + public void join() throws InterruptedException { + this.thread.join(); + } + + @Override + public void run() { + try { + while (count < maxCount) { + increment(); + System.out.println(thread.getName() + " : " + getCount()); + Thread.sleep(interval); + } + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/WaitingCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/WaitingCounter.java" new file mode 100644 index 00000000..de540ae2 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/exam04/WaitingCounter.java" @@ -0,0 +1,32 @@ +package com.nhnacademy.yunhwa._7_thread_상태.exam04; + +public class WaitingCounter implements Runnable { + private Thread thread; + RunnableCounter counter; + + public WaitingCounter(RunnableCounter counter) { + this.thread = new Thread(this); + this.counter = counter; + } + + public Thread getThread() { + return this.thread; + } + + public void start() { + this.thread.start(); + } + + public boolean isAlive() { + return thread.isAlive(); + } + + @Override + public void run() { + try { + counter.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Quiz01.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Quiz01.java" new file mode 100644 index 00000000..cc0d7a27 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Quiz01.java" @@ -0,0 +1,13 @@ +package com.nhnacademy.yunhwa._7_thread_상태.quiz01; + +public class Quiz01 { + public static void main(String[] args) { + Ticker ticker1 = new Ticker("10000n"); + Ticker ticker2 = new Ticker("20000"); + + ticker1.start(); + ticker2.start(); + + ticker1.interrupt(); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Ticker.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Ticker.java" new file mode 100644 index 00000000..c5906245 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz01/Ticker.java" @@ -0,0 +1,27 @@ +package com.nhnacademy.yunhwa._7_thread_상태.quiz01; + + +public class Ticker extends Thread { + + private long interval; + + public Ticker(String intervalTmp) { + if (intervalTmp.substring(intervalTmp.length() -1).equals("n")) { + this.interval = Long.parseLong(intervalTmp.substring(0, intervalTmp.length() -1)) / 1000000; // nanoseconds to milliseconds + } else { + this.interval = Long.parseLong(intervalTmp); + } + } + + @Override + public void run() { + try { + System.out.println("tick"); + Thread.sleep(interval); + System.out.println("tick end"); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/Quiz02.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/Quiz02.java" new file mode 100644 index 00000000..20fcddf0 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/Quiz02.java" @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._7_thread_상태.quiz02; + +public class Quiz02 { + public static void main(String[] args) throws InterruptedException { + RunnableCounter runnableCounter1 = new RunnableCounter("counter1", 10); + RunnableCounter runnableCounter2 = new RunnableCounter("counter2", 10); + RunnableCounter runnableCounter3 = new RunnableCounter("counter3", 10); + + runnableCounter1.start(); + runnableCounter2.start(); + runnableCounter3.start(); + + runnableCounter2.getThread().interrupt(); + runnableCounter1.getThread().interrupt(); + + runnableCounter2.join(); + runnableCounter3.join(); + runnableCounter1.join(); + + System.out.println("All threads stopped"); + } +} diff --git "a/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/RunnableCounter.java" "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/RunnableCounter.java" new file mode 100644 index 00000000..2d849948 --- /dev/null +++ "b/Thread/src/main/java/com/nhnacademy/yunhwa/_7_thread_\354\203\201\355\203\234/quiz02/RunnableCounter.java" @@ -0,0 +1,57 @@ +package com.nhnacademy.yunhwa._7_thread_상태.quiz02; + +public class RunnableCounter implements Runnable { + private Thread thread; + private int count = 0; + private int maxCount; + private long interval = 1000; + + + public RunnableCounter(String name, int maxCount) { + this.maxCount = maxCount; + this.thread = new Thread(this, name); + } + + public int getCount() { + return this.count; + } + + public void increment() { + this.count++; + } + + public int getMaxCount() { + return this.maxCount; + } + + public void start() { + this.thread.start(); + } + + public void stop() { + this.thread.interrupt(); + } + + public Thread getThread() { + return this.thread; + } + + public void join() throws InterruptedException { + this.thread.join(); + } + + @Override + public void run() { + try { + while (count < maxCount) { + increment(); + System.out.println(thread.getName() + " : " + getCount()); + Thread.sleep(interval); + } + System.out.println(this.thread.getName() + " end"); + } catch (InterruptedException ignore) { + System.out.println(" stopped"); + this.thread.interrupt(); + } + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Exam01.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Exam01.java new file mode 100644 index 00000000..7aa9356e --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Exam01.java @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam01; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Exam01 { + public static void main(String[] args) { + // Thread pool 생성 + ExecutorService executor = Executors.newFixedThreadPool(5); // 크기는 생성될 thread 개수보다 적게 한다. + + for (int i = 0; i < 10; i++) { + executor.submit(new Worker("Worker" + i)); // thread pool 에 Worker class 의 object 를 넣는다. + } + + // 모든 작업이 완료될 때까지 대기 + executor.shutdown(); + while (!executor.isTerminated()) { + } + + System.out.println("모든 작업이 완료되었습니다."); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Worker.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Worker.java new file mode 100644 index 00000000..9aac15fc --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam01/Worker.java @@ -0,0 +1,24 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam01; + +public class Worker implements Runnable { + private String name; + + public Worker(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public void run() { + System.out.println(this.getName() + " started"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(this.getName() + " finished"); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/DownloadWorker.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/DownloadWorker.java new file mode 100644 index 00000000..0879d3f4 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/DownloadWorker.java @@ -0,0 +1,36 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam02; + +import java.io.FileOutputStream; +import java.io.InputStream; +import java.net.URL; + +public class DownloadWorker implements Runnable { + private String url; + + public DownloadWorker(String url) { + this.url = url; + } + + + @Override + public void run() { + String fileName = url.substring(url.lastIndexOf("/") + 1); + try (InputStream inputStream = new URL(url).openStream(); + FileOutputStream outputStream = new FileOutputStream(fileName)) { + + byte[] buffer = new byte[2048]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, length); + } + + inputStream.close(); + outputStream.close(); + + System.out.println(fileName + " 다운로드 완료"); + + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/Exam02.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/Exam02.java new file mode 100644 index 00000000..4fe1bdc7 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam02/Exam02.java @@ -0,0 +1,32 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam02; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class Exam02 { + public static void main(String[] args) { + + // 내려 받을 파일의 링크 목록을 준비한다 + String[] urls = { "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.JMwL9-kHTKKJ6YhS-Xykpg", + "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.CH51Oh3xTaSSmHwhVhYrgQ", + "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.6xuIQS1YSESJmigo2ECzQw", + "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.xzEwVuqrTVm23HKK_vCm0Q", + "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.X_otcNhCRKWruinRW2gyFA", + "https://nhnacademy.dooray.com/share/drive-files/ocfkrcbb5vui.WXsaSz-ARo2DryGsEK0S_w"}; + + + // thread pool 을 생성하고, DownloadWorker object 를 생성해 등록한다 + ExecutorService executor = Executors.newFixedThreadPool(3); + + for (String url : urls) { + Runnable worker = new DownloadWorker(url); + executor.execute(worker); + } + + executor.shutdown(); + while (!executor.isTerminated()) { + } + + System.out.println("작업이 완료되었습니다."); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/Exam03.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/Exam03.java new file mode 100644 index 00000000..48b693b8 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/Exam03.java @@ -0,0 +1,22 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam03; + +public class Exam03 { + public static void main(String[] args) { + ThreadGroup group = new ThreadGroup("group"); + + RunnableCounter thread1 = new RunnableCounter(group, "worker1", 100); + RunnableCounter thread2 = new RunnableCounter(group, "worker2", 100); + + thread1.start(); + thread2.start(); + + try { + Thread.sleep(8000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + group.interrupt(); + + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/RunnableCounter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/RunnableCounter.java new file mode 100644 index 00000000..84ae9e30 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_8_thread_pool/exam03/RunnableCounter.java @@ -0,0 +1,57 @@ +package com.nhnacademy.yunhwa._8_thread_pool.exam03; + +public class RunnableCounter implements Runnable { + private Thread thread; + private int count = 0; + private int maxCount; + private long interval = 1000; + + + public RunnableCounter(ThreadGroup group, String name, int maxCount) { + this.maxCount = maxCount; + this.thread = new Thread(group, this, name); + } + + public int getCount() { + return this.count; + } + + public void increment() { + this.count++; + } + + public int getMaxCount() { + return this.maxCount; + } + + public void start() { + this.thread.start(); + } + + public void stop() { + this.thread.interrupt(); + } + + public Thread getThread() { + return this.thread; + } + + public void join() throws InterruptedException { + this.thread.join(); + } + + @Override + public void run() { + try { + while (count < maxCount) { + increment(); + System.out.println(thread.getName() + " : " + getCount()); + Thread.sleep(interval); + } + System.out.println(this.thread.getName() + " end"); + } catch (InterruptedException ignore) { + System.out.println(" stopped"); + this.thread.interrupt(); + } + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/Exam01.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/Exam01.java new file mode 100644 index 00000000..f0d0a35e --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/Exam01.java @@ -0,0 +1,24 @@ +package com.nhnacademy.yunhwa._9_demon_thread; + + +public class Exam01 { + public static void main(String[] args) { + RunnableCounter counter1 = new RunnableCounter("counter1", 100); + RunnableCounter counter2 = new RunnableCounter("counter2", 100); + + counter2.setDemon(true); + + counter1.start(); + counter2.start(); + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + counter1.stop(); + + System.out.println("Main Thread terminated"); + } +} diff --git a/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/RunnableCounter.java b/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/RunnableCounter.java new file mode 100644 index 00000000..eb65ae03 --- /dev/null +++ b/Thread/src/main/java/com/nhnacademy/yunhwa/_9_demon_thread/RunnableCounter.java @@ -0,0 +1,51 @@ +package com.nhnacademy.yunhwa._9_demon_thread; + +public class RunnableCounter implements Runnable { + + private String name; + private int count; + private int maxCount; + private Thread thread; + + public RunnableCounter(String name, int maxCount) { + this.name = name; + this.maxCount = maxCount; + this.count = 0; + this.thread = new Thread(this, name); + } + + public Thread getThread() { + return this.thread; + } + + + public void start() { + this.thread.start(); + } + + public void setDemon(boolean flag) { + this.thread.setDaemon(flag); + } + + public void stop() { + this.thread.interrupt(); + } + + @Override + public void run() { + while (this.count < this.maxCount) { + try { + if (Thread.currentThread().isInterrupted()) { + System.out.println("isinterrupted 가 참입니다. while 문 빠져나옵니다."); + break; + } + this.count++; + System.out.println(this.name + "'s count : " + this.count); + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("interrupt 메서드 호출하여 setting 하였습니다."); + } + } + } +}