生产者消费者模式
@Slf4j(topic = "c.Test02")
public class Test02 {
public static void main(String[] args) {
MessageQueue messageQueue = new MessageQueue(2);
for (int i = 0; i < 3; i++) {
int id = i;
new Thread(()->{
messageQueue.put(new Message(id,"内容"+id));
},"生产者"+i).start();
}
new Thread(()->{
while(true){
try {
Thread.sleep(1000);
messageQueue.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"消费者").start();
}
}
@Slf4j(topic = "c.MessageQueue")
class MessageQueue{
private LinkedList<Message> messageQueue = new LinkedList<>();//存放消息的队列
private int capity;//消息队列的容量
public MessageQueue(int capity) {
this.capity = capity;
}
//获取消息
public Message get(){
synchronized (messageQueue){
//如果队列为空
while(messageQueue.isEmpty()){
try {
messageQueue.wait();
log.debug("没消息了,消费者等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message message = messageQueue.removeFirst();
//消费者消费了,通知生产者继续生产
messageQueue.notifyAll();
log.debug("消费者消费了{}",message);
return message;
}
}
public void put(Message message){
synchronized (messageQueue){
if(messageQueue.size() >= capity){
log.debug("容量满了,生产者等待");
try {
messageQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,生产者继续生产
messageQueue.add(message);
log.debug("生产者生产了{}",message);
//有产品了通知消费者
messageQueue.notifyAll();
}
}
}
final class Message{
private int id;
private Object value;
public Message(int id, Object value) {
this.id = id;
this.value = value;
}
@Override
public String toString() {
return "Message{" +
"id=" + id +
", value=" + value +
'}';
}
public int getId() {
return id;
}
public Object getValue() {
return value;
}
}
1.1 区别
这个需要和mq的消息队列区分开,这是属于线程之间的,mq是属于进程之间。
1.2 消息存放和获取方式
MessageQueue作为一个消息队列,负责消费者和生产者进行通信,消费者消费消息是从队头获取,生产者生产消息是从队尾生产。
1.3消费者和生产者的工作方式
当消费者没有消息消费的时候就会进入等待,等待生产者生产消息,当生产者生产了消息,就会通知消费者去消费。当生产者生产消息超过容量,就会等待,直到消费者消费消息后才会继续生产
二、park&&unpark 与wait&¬ify
1.1 区别
- wait-notify需要配合Object monitor使用,park-unpark不需要。
- park-unpark可以先unpark,和wait-notify不能先notify
- unpark可以指定线程,notify只能唤醒其中一个或全部
1.2 原理
每个线程都有一个parker对象,由_counter,_cond,_metex组成。
park:
unpark