java 消费者生产模式_[java] 生产者消费者模式

producer-consumer 模式

生产者负责创建消息

消费者负责消费

本文使用 java 实现,主要使用 BlockingQueue

关于 BlockingQueue

BlockingQueue--阻塞队列,

当消息满的时候尝试再放入消息时会阻塞,

当消息空的时候尝试取消息时也会阻塞。

测试代码 public static void main(String[] args) throws InterruptedException {

BlockingQueue queue = new LinkedBlockingQueue<>(5);

for (int i=0; i<8; i++) {

LOGGER.info("i=" +i);

queue.put(i + "th");

}

for (int i=0; i<7; i++) {

String result = queue.take();

System.out.println(result);

}

} 21:49:30.823 [main] INFO com.carl.producer_consumer.TaskQueue - i=0

21:49:30.827 [main] INFO com.carl.producer_consumer.TaskQueue - i=1

21:49:30.827 [main] INFO com.carl.producer_consumer.TaskQueue - i=2

21:49:30.827 [main] INFO com.carl.producer_consumer.TaskQueue - i=3

21:49:30.827 [main] INFO com.carl.producer_consumer.TaskQueue - i=4

21:49:30.827 [main] INFO com.carl.producer_consumer.TaskQueue - i=5

可以看到当尝试 put 第 6 个数据的时候,队列阻塞了

所以日常工作中生产者与消费者在不同的系统中或在不同的线程中工作

package com.carl.producer_consumer;

public class Task {

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getStatus() {

return status;

}

public void setStatus(String status) {

this.status = status;

}

private String name;

private String status;

Task(String name, String status) {

this.name = name;

this.status = status;

}

} package com.carl.producer_consumer;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

public class TaskQueue {

private BlockingQueue queue = new LinkedBlockingQueue(3);

public TaskQueue() {

}

public Task take() throws InterruptedException {

return queue.take();

}

public void put(Task task) throws InterruptedException {

queue.put(task);

}

} package com.carl.producer_consumer;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class TaskProducer {

private static final Logger LOGGER = LoggerFactory.getLogger(TaskProducer.class);

private TaskQueue queue;

TaskProducer(TaskQueue taskQ) {

this.queue = taskQ;

}

public void producer(Task task) throws InterruptedException {

LOGGER.debug(task.getName() + "," + task.getStatus());

queue.put(task);;

}

} package com.carl.producer_consumer;

import java.util.concurrent.BlockingQueue;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class TaskConsumer {

private static Logger LOGGER = LoggerFactory.getLogger(TaskConsumer.class);

private TaskQueue queue;

TaskConsumer(TaskQueue queue) {

this.queue = queue;

}

public void consumer() throws InterruptedException {

Task task = queue.take();

LOGGER.debug(task.getName() + " is consume " + task.getStatus());

}

} package com.carl.producer_consumer;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class Main {

static TaskQueue taskQ = new TaskQueue();

static ExecutorService threadPool = Executors.newFixedThreadPool(6);

static int i=0;

private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);

public static void main(String[] args) {

TaskProducer producer = new TaskProducer(taskQ);

threadPool.submit(() ->{

while(true) {

i++;

producer.producer(new Task("the "+i+" queue:", "create finish"));

Thread.sleep(1000);

}

});

TaskConsumer consumer = new TaskConsumer(taskQ);

threadPool.submit(() ->{

while(true) {

consumer.consumer();

Thread.sleep(3000);

}

});

}

} 08:11:47.949 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 1 queue:,create finish

08:11:47.952 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 1 queue: is consume create finish

08:11:48.952 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 2 queue:,create finish

08:11:49.953 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 3 queue:,create finish

08:11:50.953 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 2 queue: is consume create finish

08:11:50.953 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 4 queue:,create finish

08:11:51.953 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 5 queue:,create finish

08:11:52.953 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 6 queue:,create finish

08:11:53.953 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 3 queue: is consume create finish

08:11:54.953 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 7 queue:,create finish

08:11:56.953 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 4 queue: is consume create finish

08:11:57.963 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 8 queue:,create finish

08:11:59.954 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 5 queue: is consume create finish

08:12:00.954 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 9 queue:,create finish

08:12:02.954 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 6 queue: is consume create finish

08:12:03.954 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 10 queue:,create finish

08:12:05.954 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 7 queue: is consume create finish

08:12:06.954 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 11 queue:,create finish

08:12:08.954 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 8 queue: is consume create finish

08:12:09.955 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 12 queue:,create finish

08:12:11.955 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 9 queue: is consume create finish

08:12:12.955 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 13 queue:,create finish

08:12:14.955 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 10 queue: is consume create finish

08:12:15.955 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 14 queue:,create finish

08:12:17.955 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 11 queue: is consume create finish

08:12:18.955 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 15 queue:,create finish

08:12:20.956 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 12 queue: is consume create finish

08:12:21.956 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 16 queue:,create finish

08:12:23.956 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 13 queue: is consume create finish

08:12:24.956 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 17 queue:,create finish

08:12:26.956 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 14 queue: is consume create finish

08:12:27.956 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 18 queue:,create finish

08:12:29.957 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 15 queue: is consume create finish

08:12:30.957 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 19 queue:,create finish

08:12:32.957 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 16 queue: is consume create finish

08:12:33.957 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 20 queue:,create finish

08:12:35.957 [pool-1-thread-2] DEBUG com.carl.producer_consumer.TaskConsumer - the 17 queue: is consume create finish

08:12:36.957 [pool-1-thread-1] DEBUG com.carl.producer_consumer.TaskProducer - the 21 queue:,create finish

我的理解

虽然生产者和消费者在时间延迟上不一致,但由于阻塞的关系,它会等到有消息被取出之后再生产,

这可能是一种 “背压(backpressure)” 说可能是因为还不了解背压的真正概念

背压的概念是在 RXJAVA 模式中了解到的,等写出 demo 的时候再说明吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值