生產消費者模式
使用阻塞佇列控制訊息的產生和消費
程式碼實現:
class MessageQueue {
private final LinkedList<Message> list = new LinkedList<>();
private final int capacity;
public MessageQueue (int capacity) {
this.capacity = capacity;
}
public Message take () {
boolean first = true;
synchronized (list) {
// 空佇列檢測
while (list.isEmpty()) {
if (first) {
System.out.println("queue is empty!");
first = false;
}
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.notifyAll();
return list.removeFirst();
}
}
public void put (Message message) {
boolean first = true;
synchronized (list) {
// 溢位檢測
while (list.size() == capacity) {
if (first) {
System.out.println("queue is full!");
first = false;
}
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.addLast(message);
list.notifyAll();
}
}
}
final class Message {
private final int id;
private final Object message;
public Message(int id, Object message) {
this.id = id;
this.message = message;
}
@Override
public String toString() {
return "Message{" +
"id=" + id +
", message=" + message +
'}';
}
}
測試程式碼:
public class ProduceConsume {
public static void main(String[] args) {
MessageQueue queue = new MessageQueue(3);
for (int i = 0; i < 6; i++) {
int id = i;
new Thread(() -> {
Message message = new Message(id, "訊息" + id);
queue.put(message);
System.out.println("put message:" + message);
}, "producer:" + i).start();
}
new Thread(() -> {
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("take message:" + queue.take());
}
}, "consumer").start();
}
}
執行效果:
本作品採用《CC 協議》,轉載必須註明作者和本文連結