μΆμ²
ChatGPT
μμ°μ-μλΉμ(Producer-Consumer) ν¨ν΄μ λ©ν°μ€λ λ νκ²½μμ μμ°μ(Producer)μ μλΉμ(Consumer) μ€λ λ κ°μ λ°μ΄ν°λ₯Ό μμ νκ² κ³΅μ νκΈ° μν λμμΈ ν¨ν΄μ΄λ€. μ΄ ν¨ν΄μ 곡μ μμμ λκ³ μ¬λ¬ μ€λ λκ° λμμ μ κ·Όν λ λ°μν μ μλ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ μ¬μ©λλ©°, μΌλ°μ μΌλ‘ λ²νΌ(ν)λ₯Ό μ¬μ©ν΄ λ°μ΄ν°λ₯Ό μ£Όκ³ λ°λλ€.
1. μμ°μ-μλΉμ ν¨ν΄μ κ°λ
μμ°μ Producer
λ°μ΄ν°λ₯Ό μμ±νλ μ€λ λλ‘, μμ°λ λ°μ΄ν°λ₯Ό λ²νΌλ νμ μ μ₯νλ€.
μλΉμ Consumer
μμ°μκ° μμ±ν λ°μ΄ν°λ₯Ό λ²νΌμμ κ°μ Έμ μ²λ¦¬νλ μ€λ λ
λ²νΌλ μμ°μκ° λ°μ΄ν°λ₯Ό μ μ₯νκ³ , μλΉμκ° λ°μ΄ν°λ₯Ό κ°μ Έμ€λ 곡μ λ μμμ΄λ€. λ²νΌκ° κ°λ μ°¬ κ²½μ°, μμ°μλ λ°κΈ°νκ³ , λ²νΌκ° λΉμ΄ μλ κ²½μ°, μλΉμλ λκΈ°ν΄μΌ νλ€. μμ°μμ μλΉμκ° λκΉμ λ²νΌμ μ κ·Όνλ κ²½μ° λκΈ°νκ° νμνλ€.
2. μμ°μ-μλΉμ ν¨ν΄μ λμ μ리
μ΄ ν¨ν΄μ λκΈ°ν 맀컀λμ¦μ ν΅ν΄ λ°μ΄ν°λ₯Ό μμ νκ² κ³΅μ νκ³ , μμ°μκ° λ°μ΄ν°λ₯Ό λ μ΄μ μμ±νμ§ μλλ‘ νκ³ , μλΉμκ° λ°μ΄ν°λ₯Ό μ²λ¦¬ν μ μλ μν©μ λ§λ€μ΄μ€λ€.
- μμ°μλ λ²νΌμ λ°μ΄ν°λ₯Ό μΆκ°νκ³ , λ²νΌκ° κ°λ μ°¨λ©΄ λ μ΄μ λ°μ΄ν°λ₯Ό μΆκ°ν μ μκΈ° λλ¬Έμ λκΈ°νλ€.
- μλΉμλ λ²νΌμμ λ°μ΄ν°λ₯Ό κ°μ Έκ°λ©°, λ²νΌκ° λΉμ΄ μμΌλ©΄ λ°μ΄ν°λ₯Ό κ°μ Έμ¬ μ μκΈ° λλ¬Έμ λκΈ°νλ€.
- μ΄ κ³Όμ μμ λ²νΌμ ν¬κΈ°λ₯Ό κ³ λ €ν λκΈ°νκ° νμνλ©°, μμ°μ-μλΉμ λ¬Έμ λ λκ° λ²νΌλ₯Ό κΈ°μ€μΌλ‘ λ°μ΄ν°λ₯Ό μμ νκ² κ³΅μ νλ λ°©μμΌλ‘ ν΄κ²°λλ€.
3. μ£Όμ λ¬Έμ μ λ° ν΄κ²° λ°©λ²
1. λμμ± λ¬Έμ
μ¬λ¬ μ€λ λκ° λμμ λ²νΌμ μ κ·Όνλ μν©μμ, λ°μ΄ν°μ μΌκ΄μ±μ μ μ§νκΈ° μν΄ λκΈ°νκ° νμνλ€. μλ°μμλ synchronized(), wait(), notify(), notifyAll()κ³Ό κ°μ λκΈ°ν 맀컀λμ¦μ ν΅ν΄ μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ€.
2. λ²νΌκ° κ°λ μ°¬ κ²½μ° Overflow
λ²νΌκ° κ°λ μ°¨λ©΄ μμ°μλ λ μ΄μ λ°μ΄ν°λ₯Ό μΆκ°ν μ μκΈ° λλ¬Έμ λκΈ°νλ€. μ΄ μνλ λ²νΌκ° λΉμμ§ λκΉμ§ μ§μλλ€.
3. λ²νΌκ° λΉμ΄ μλ κ²½μ° Underflow
λ²νΌκ° λΉμ΄ μμΌλ©΄ μλΉμλ λ°μ΄ν°λ₯Ό κ°μ Έμ¬ μ μμΌλ―λ‘, μμ°μκ° μλ‘μ΄ λ°μ΄ν°λ₯Ό μΆκ°ν λκΉμ§ λκΈ°ν΄μΌ νλ€.
4. μμ°μ-μλΉμ ν¨ν΄μ κ·ν λ°©λ²
μλ°μμ μμ°μ-μλΉμ ν¨ν΄μ ꡬνν λλ μΌλ°μ μΌλ‘ BlockinigQueueλ₯Ό μ¬μ©νκ±°λ, synchronized, wait(), notify() λ©μλλ₯Ό ν΅ν΄ μ§μ λκΈ°νλ₯Ό μ μ΄ν μ μλ€.
1. BlockingQueueλ₯Ό μ¬μ©ν μμ°μ-μλΉμ ν¨ν΄
BlockingQueueλ νκ° κ°λ μ°Όμ λ μλμΌλ‘ μμ°μλ₯Ό λκΈ°μν€κ³ , νκ° λΉμμ λ μλμΌλ‘ μλΉμλ₯Ό λκΈ°μν€λ λκΈ°ν νμ΄λ€.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerExample {
public static void main(String[] args) {
// ν¬κΈ°κ° 5μΈ BlockingQueue μμ±
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(5);
// μμ°μ μ€λ λ
Thread producer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
System.out.println("Produced: " + i);
queue.put(i); // νκ° κ°λ μ°¨λ©΄ λκΈ°
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// μλΉμ μ€λ λ
Thread consumer = new Thread(() -> {
try {
for (int i = 1; i <= 10; i++) {
Integer value = queue.take(); // νκ° λΉμ΄ μμΌλ©΄ λκΈ°
System.out.println("Consumed: " + value);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
μΆλ ₯ μμ
Produced: 1
Produced: 2
Produced: 3
Consumed: 1
Consumed: 2
Produced: 4
Consumed: 3
...
- BlockingQueueλ μμ°μ-μλΉμ ν¨ν΄μμ λκΈ°νλ₯Ό λͺ μμ μΌλ‘ μ²λ¦¬νμ§ μμλ λλ€. νκ° κ°λ μ°¨λ©΄ μλμΌλ‘ μμ°μκ° λκΈ°νκ³ , λΉμ΄ μμΌλ©΄ μλΉμκ° λκΈ°νλ€.
- put() λ©μλλ νκ° κ°λ μ°¨λ©΄ λκΈ°νκ³ , take() λ©μλλ νκ° λΉμ΄ μμΌλ©΄ λκΈ°νλ€.
2. synchronized, wait(), notify()λ₯Ό μ΄μ©ν μμ°μ-μλΉμ ν¨ν΄
λ€μμ synchronized ν€μλμ wait(), notify() λ©μλλ₯Ό μ¬μ©ν μμμ΄λ€. wait()λ μ€λ λλ₯Ό λκΈ° μνλ‘ λ§λ€κ³ , notify()λ λκΈ° μ€μΈ μ€λ λλ₯Ό κΉ¨μ°λ λμμ μννλ€.
import java.util.LinkedList;
import java.util.Queue;
class ProducerConsumer {
private final Queue<Integer> queue = new LinkedList<>();
private final int MAX_SIZE = 5;
// μμ°μ λ©μλ
public void produce() throws InterruptedException {
int value = 0;
while (true) {
synchronized (this) {
while (queue.size() == MAX_SIZE) {
wait(); // νκ° κ°λ μ°¨λ©΄ λκΈ°
}
System.out.println("Produced: " + value);
queue.add(value++);
notify(); // μλΉμμκ² μ νΈλ₯Ό λ³΄λ΄ λκΈ° μνμμ κΉ¨μ
}
}
}
// μλΉμ λ©μλ
public void consume() throws InterruptedException {
while (true) {
synchronized (this) {
while (queue.isEmpty()) {
wait(); // νκ° λΉμ΄ μμΌλ©΄ λκΈ°
}
int value = queue.poll();
System.out.println("Consumed: " + value);
notify(); // μμ°μμκ² μ νΈλ₯Ό λ³΄λ΄ λκΈ° μνμμ κΉ¨μ
}
}
}
}
public class ProducerConsumerExample {
public static void main(String[] args) {
ProducerConsumer pc = new ProducerConsumer();
// μμ°μ μ€λ λ
Thread producer = new Thread(() -> {
try {
pc.produce();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// μλΉμ μ€λ λ
Thread consumer = new Thread(() -> {
try {
pc.consume();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
μΆλ ₯ μμ
Produced: 0
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Consumed: 0
Consumed: 1
Produced: 5
Consumed: 2
Produced: 6
...
- wait() : μμ°μκ° νκ° κ°λ μ°Όμ λ λλ μλΉμκ° νκ° λΉμμ λ, μ€λ λλ₯Ό λκΈ° μνλ‘ λ§λ λ€.
- notify() : μμ°μ λλ μλΉμκ° λκΈ° μνμμ κΉ¨μ΄λκ² νμ¬ μμ μ κ³μ μνν μ μλλ‘ νλ€.
5. μμ°μ-μλΉμ ν¨ν΄μ μ₯μ
λμμ± μ μ΄
μμ°μμ μλΉμκ° λμμ λ°μ΄ν°λ₯Ό μ²λ¦¬νλλΌλ λκΈ°νλ₯Ό ν΅ν΄ λ°μ΄ν°μ 무결μ±μ 보μ₯ν μ μλ€.
ν¨μ¨μ μμ μ¬μ©
λ²νΌμ ν¬κΈ°λ₯Ό μ νν΄ λ©λͺ¨λ¦¬ μμμ μ¬μ©μ μ μ΄ν μ μμΌλ©°, μμ°μμ μλΉμκ° ν¨μ¨μ μΌλ‘ νλ ₯νμ¬ μμ μ μ²λ¦¬ν μ μλ€.
λ©λ¦¬μ€λ λ νκ²½μμμ μμ μ±
μμ°μμ μλΉμκ° λκΈ°νλ λ°©μμΌλ‘ λ°μ΄ν°λ₯Ό μ²λ¦¬νλ―λ‘, μ€λ λ κ°μ μΆ©λμ λ°©μ§ν μ μλ€.
6. μμ°μ-μλΉμ ν¨ν΄μ μμ©
μ΄ ν¨ν΄μ μ£Όλ‘ λ€μ€ μ€λ λ νλ‘κ·Έλλ°μμ μ¬μ©λλ©°, λ€μν μν©μμ μμ©λ μ μλ€.
μμ λκΈ°μ΄
μμ°μκ° μμ μ μμ±νκ³ μλΉμκ° μ²λ¦¬νλ μμ νμμ μ¬μ©λλ€.
λ©μμ§ μ²λ¦¬ μμ€ν
λ©μμ§λ₯Ό μμ±νλ μμ°μμ κ·Έ λ©μμ§λ₯Ό μ²λ¦¬νλ μλΉμλ₯Ό λΆλ¦¬νμ¬, λ©μμ§ νλ₯Ό μ¬μ©ν΄ μμ νκ² λ©μμ§λ₯Ό μ²λ¦¬νλ€.
λ°μ΄ν° μ€νΈλ¦¬λ°
μ€νΈλ¦¬λ° λ°μ΄ν°μ μμ°μ(λ°μ΄ν° μ 곡μ)μ μλΉμ(λ°μ΄ν° μ²λ¦¬μ)κ° νλ ₯νμ¬ λ°μ΄ν°λ₯Ό μ€μκ°μΌλ‘ μ²λ¦¬ν μ μλ€.
κ²°λ‘
μμ°μ-μλΉμ ν¨ν΄μ λ©ν°μ€λ λ νκ²½μμ λ°μ΄ν°λ₯Ό μμ νκ² κ³΅μ νλ λ°©λ²μΌλ‘, μμ°μ μ€λ λ λ°μ΄ν°λ₯Ό μμ±νκ³ μλΉμ μ€λ λκ° κ·Έ λ°μ΄ν°λ₯Ό μ²λ¦¬ν λ μμ£Ό μ¬μ©λλ€. μ΄ ν¨ν΄μ λμμ± λ¬Έμ λ₯Ό ν΄κ²°νλ©°, BlockingQueueμ κ°μ λκΈ°νλ νλ₯Ό μ¬μ©νλ©΄ 볡μ‘ν λκΈ°ν μ½λλ₯Ό νΌν μ μλ€.
'λΉ κ΅¬λ© μ±μ°κΈ°' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[μκ³ λ¦¬μ¦] μ μ리 μ λ ¬ In-Place Sorting (1) | 2024.09.15 |
---|---|
[Java] Queue μΈν°νμ΄μ€ (1) | 2024.09.14 |
[Java] TreeMap ꡬν (0) | 2024.09.14 |
[Java] NavigableMap (0) | 2024.09.14 |
[Java] μμ° μμ Natural Ordering (0) | 2024.09.11 |