简介
生产者消费者模式中,有两类线程:若干个生产者线程和若干个消费这线程。生产者主要负责提交用户的请求。消费这用于处理生产者提交的任务。生产者消费者通过共享的内存缓冲区进行数据通信。
生产者消费之间并不是直接通信,从而可以减少他们之间的耦合。生产者不需要消费者直接存在,消费这也不需要知道生产者的存在。内存缓冲区主要的功能是实现数据在多线程间的共享。此外,通过缓冲区可以缓解生产者和消费者之间的性能差异。
代码实现
测试类:
package com.cyan.Producer_Consumer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @description: 三个生产者消费者进行测试
*/
public class Producer_Consumer_Test {
public static void main(String[] args) throws InterruptedException {
//创建任务队列
BlockingQueue<Task> tasks = new LinkedBlockingDeque<>();
//创建生产者和消费者
Producer p1 = new Producer(tasks);
Producer p2 = new Producer(tasks);
Producer p3 = new Producer(tasks);
Consumer c1 = new Consumer(tasks);
Consumer c2 = new Consumer(tasks);
Consumer c3 = new Consumer(tasks);
//创建线程池启动生产者和消费者
ExecutorService executorService = Executors.newFixedThreadPool(6);
executorService.execute(p1);
executorService.execute(p2);
executorService.execute(p3);
executorService.execute(c1);
executorService.execute(c2);
executorService.execute(c3);
Thread.sleep(10*1000);
//生产者创建10s钟的任务,然后停止生产
p1.stop();
p2.stop();
p3.stop();
System.out.println("生产者都他娘的跑完了!!!");
}
}
任务实体类:
package com.cyan.Producer_Consumer;
/**
* @description:
* @author: cyan
* @create: 2018-12-23 12:49
*/
public class Task {
private String name;
public String getName() {
return name;
}
public Task(String name) {
this.name = name;
}
@Override
public String toString() {
return "Task{" +
"name='" + name + '\'' +
'}';
}
}
生产者:
package com.cyan.Producer_Consumer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @description: 生产者消费者模式是多线程的一种程序优化设计模式,所以生产者和消费者都是线程。
* 两者共享内存缓冲区,缓冲区中共享需要创建的任务。
*/
public class Producer implements Runnable {
//判断生产者是否正在运行的标志
private volatile boolean isRunning = true;
//共享的内存缓冲区
private BlockingQueue<Task> taskQueue;
//模拟生产者创建任务的过程
private final static int SLEEP = 1000;
//创建生产者的时候将任务队列传递进去
public Producer(BlockingQueue<Task> taskQueue) {
this.taskQueue = taskQueue;
}
/**
*@Param: []
*@return: void
*@Description: 生产者具体创建任务的处理过程
*/
@Override
public void run() {
Task task = null;
System.out.println("Producer is running :" + Thread.currentThread().getName());
String name = "";
try {
while (true) {
if (isRunning) {
Thread.sleep(SLEEP);
name = name + "aaa";
task = new Task(Thread.currentThread().getName() + " " + name + "aaaa");
System.out.println("Producer :" + Thread.currentThread().getName() + " is Running !!!");
if (!taskQueue.offer(task, 2, TimeUnit.SECONDS)) {
System.out.println("fail to add Task!!!");
}
} else {
Thread.sleep(SLEEP);
task = new Task(Thread.currentThread().getName() + " " + "生产完毕~!!!");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
*@Param: []
*@return: void
*@Description: 关闭生产者
*/
public void stop() {
isRunning = false;
}
}
消费者:
package com.cyan.Producer_Consumer;
import java.util.concurrent.BlockingQueue;
/**
* @description:
*/
public class Consumer implements Runnable {
//任务队列
private static BlockingQueue<Task> taskQueue = null;
//模拟消费者处理的任务的流程
private static final int SLEEP = 1500;
//创建消费者的时候将共享的内存任务队列传入
public Consumer(BlockingQueue<Task> taskQueue) {
this.taskQueue = taskQueue;
}
/**
*@Param: []
*@return: void
*@Description: 处理生产者提交的任务
*/
@Override
public void run() {
try {
while (true) {
//从任务队列中获取任务进行处理,内部调用LinkedBlockQueue的takeFast()
Task task = taskQueue.take();
System.out.println("Current Consumer : " + Thread.currentThread().getName
//从任务队列中移除当前任务
taskQueue.remove(task);
System.out.println("Current Task is :" + task.getName());
Thread.sleep(SLEEP);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}