为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这种生产消费能力不均衡的问题,所以便有了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

这个阻塞队列就是用来给生产者和消费者解耦的。纵观大多数设计模式,都会找一个第三者出来进行解耦,如工厂模式的第三者是工厂类,模板模式的第三者是模板类。

生产者消费者模式实战

利用BlockingQueue

package com;

import java.util.Random;
import java.util.concurrent.BlockingQueue; public class Comsumer implements Runnable {
private BlockingQueue<PCData> queue;
private static final int SLEEPTIME = 1000;
public Comsumer(BlockingQueue<PCData> queue) {
this.queue = queue;
}
@Override
public void run() {
System.out.println("start Consumer Id:"+Thread.currentThread().getId());
Random r = new Random();
Boolean isrunning = true;
try {
while(isrunning){
PCData data = queue.take();
if(data != null){
System.out.println("Comsumer data:"+data);
Thread.sleep(r.nextInt(SLEEPTIME));
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
}

  

package com;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; public class Producer implements Runnable{
private volatile boolean isRunning = true;
//内存缓冲区
private BlockingQueue<PCData> queue;
//总数 AtomicInteger
private static AtomicInteger count = new AtomicInteger();
private static final int SLEEPTIME = 1000; public Producer(BlockingQueue<PCData> queue){
this.queue = queue;
} public void run(){
PCData data = null;
Random r = new Random();
System.out.println("start producting id:"+ Thread.currentThread().getId());
while(isRunning){
try {
while(isRunning){
Thread.sleep(r.nextInt(SLEEPTIME));
data = new PCData(count.incrementAndGet());
if(!queue.offer(data,2,TimeUnit.SECONDS)){
System.out.println("加入队列失败");
}else{
System.out.println("Producer data:"+data);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
} public void stop(){
isRunning = false;
}
}

  

package com;

public class PCData {
private final int intData;
public PCData(int d){
intData = d;
} public PCData(String d){
intData = Integer.valueOf(d);
} public int getData(){
return intData;
} @Override
public String toString(){
return ""+intData;
}
}

  

package com;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; public class Main {
public static void main(String[] args) throws InterruptedException{
BlockingQueue<PCData> queue = new LinkedBlockingQueue<>(10);
Producer p1 = new Producer(queue);
Producer p2 = new Producer(queue);
Producer p3 = new Producer(queue);
Comsumer c1 = new Comsumer(queue);
Comsumer c2 = new Comsumer(queue);
Comsumer c3 = new Comsumer(queue);
ExecutorService service = Executors.newCachedThreadPool();
service.execute(p1);
service.execute(p2);
service.execute(p3);
service.execute(c1);
service.execute(c2);
service.execute(c3);
Thread.sleep(10*1000);
p1.stop();
p2.stop();
p3.stop();
Thread.sleep(3000);
service.shutdown();
}
}

  利用notifyAll和wait

package com;

import java.util.List;

public class Consumer implements Runnable{
private List<PCData> queue;
public Consumer(List<PCData> queue){
this.queue = queue;
} @Override
public void run() {
while(true){
PCData data = null;
try {
synchronized (queue) {
if(queue.size() == 0){
System.out.println(Thread.currentThread().getId()+"队列为空,无法消费");
queue.notifyAll();
queue.wait();
}else{
data = queue.remove(0);
System.out.println(Thread.currentThread().getId()+"消费:"+data);
}
}
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

  

package com;

import java.util.List;
import java.util.Random; public class Producer implements Runnable {
private List<PCData> queue;
private int length; public Producer(List<PCData> queue,int length){
this.queue = queue;
this.length = length;
} @Override
public void run() {
while(true){
Random r = new Random();
PCData data = new PCData(r.nextInt(100));
try {
synchronized (queue) {
if(queue.size() >= length){
System.out.println(Thread.currentThread().getId()+"队列满了,无法加入 ");
queue.notifyAll();
queue.wait();
}else{
queue.add(data);
System.out.println(Thread.currentThread().getId()+"生产了:"+data);
}
}
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
} } }

  

package com;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Main {
public static void main(String[] args){
List<PCData> queue = new ArrayList<>();
int length =10;
Producer p1 = new Producer(queue, length);
Producer p2 = new Producer(queue, length);
Producer p3 = new Producer(queue, length);
Consumer c1 = new Consumer(queue);
Consumer c2 = new Consumer(queue);
Consumer c3 = new Consumer(queue);
ExecutorService service = Executors.newCachedThreadPool();
service.execute(p1);
service.execute(p2);
service.execute(p3);
service.execute(c1);
service.execute(c2);
service.execute(c3);
}
}

  

Java生产者消费者模式的更多相关文章

  1. 基于Java 生产者消费者模式(详细分析)

    Java 生产者消费者模式详细分析 本文目录:1.等待.唤醒机制的原理2.Lock和Condition3.单生产者单消费者模式4.使用Lock和Condition实现单生产单消费模式5.多生产多消费模 ...

  2. Java 生产者消费者模式详细分析

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

  3. java生产者/消费者模式实现——一生产者一消费者(操作值)

    胶多不粘话多不甜,直接上代码: 生产者类: /** * Created by 51304 on 2016/2/28. */ public class P { private String lock; ...

  4. Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...

  5. java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】

    java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...

  6. java ReentrantLock结合条件队列 实现生产者-消费者模式 以及ReentratLock和Synchronized对比

    package reentrantlock; import java.util.ArrayList; public class ProviderAndConsumerTest { static Pro ...

  7. Java 学习笔记 使用并发包ReentrantLock简化生产者消费者模式代码

    说明 ReentrantLock是java官方的一个线程锁类,ReentarntLock实现了Lock的接口 我们只需要使用这个,就可以不用使用synchronized同步关键字以及对应的notify ...

  8. Java多线程-----实现生产者消费者模式的几种方式

       1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...

  9. java设计模式之生产者/消费者模式

    什么是生产者/消费者模式? 某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产者:而处理数据的模块,就称为消费者 ...

随机推荐

  1. 晒一下MAC下终端颜色配置

    效果图: ~/.vimrc 配置 filetype on set history=1000 set background=dark syntax on set autoindent set smart ...

  2. 使用代码获得Netweaver里某个software component和C4C的版本

    有同事问如何通过代码的方式获得Netweaver里某个Software component的版本信息,以及Cloud for Customer(C4C)的版本信息. Netweaver 点了Detai ...

  3. 多目标检测分类 RCNN到Mask R-CNN

    最近做目标检测需要用到Mask R-CNN,之前研究过CNN,R-CNN:通过论文的阅读以及下边三篇博客大概弄懂了Mask R-CNN神经网络.想要改进还得努力啊... 目标检测的经典网络结构,顺序大 ...

  4. UVA 1615 Highway 高速公路 (区间选点)

    题意:在一条线段上选出尽量少的点,使得和所有给出的n个点距离不超过D. 分别计算出每个点在线段的满足条件的区间,然后就转化成了区间选点的问题了,按照右端点排序,相同时按照左端点排序,按照之前的排序一定 ...

  5. NOIP模拟赛 水灾

    大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY所在的城市可以用一个N*M(N,M<=50)的地图表示,地图上 ...

  6. NOIP模拟赛 数列

    Problem 2 数列(seq.cpp/c/pas) [题目描述] a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1]  (x>3) 求a数列的第n项对1000000007 ...

  7. pycharm安装 suds模块报错:AttributeError: module 'pip' has no attribute 'main'

    需求:安装suds模块 遇到的问题: 一.报错信息:[file][Default Settint]---Project Interpreter 点击 搜索suds安装模块报错 解决:依据上图提示找到C ...

  8. 01创建线程CreateThread和_beginthreadex

    Windows多线程之线程创建 一. 线程创建函数 CreateThread 1. 函数原型 HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRI ...

  9. 帮助解决NoSuchMethodError

    排查出具体的类,然后将冲突的类删除掉即可 Method[] methods = Base64.class.getMethods(); // 输出实际jar包路径 System.out.println( ...

  10. Linux异常处理体系结构

    arm11处理器裸机的异常与中断处理参考: [OK6410裸机程序]异常处理 [OK6410裸机程序]按键中断 另外参考一篇:Linux中断体系结构 在ARM V4及V4T以后的大部分处理器中,中断向 ...