生产者--消费者模式

生产者--消费者模式

1、示例:

class Resource{
	private String name;
	private int count = 1;
	private Boolean flag = false;

	public synchronized void set(String name){
		if(flag)
			try {
				this.wait();//this代表调用函数线程
			} catch (InterruptedException e) {}

		this.name = name+"__ " + count++;
		System.out.println(Thread.currentThread().getName()+ "......生产者" + this.name);
		flag = true;
		this.notifyAll();
	}

	public synchronized void show(){
		if(!flag)
			try {
				this.wait();
			} catch (InterruptedException e) {
			}

		System.out.println(Thread.currentThread().getName()+"消费者"+ this.name);
		flag = false;
		this.notifyAll();
	}
}

//定义生产类Producter,生产商品

class Producter implements Runnable{
	private Resource r;
	Producter(Resource r){
		this.r = r;
	}
	public void run(){
		while(true){
			r.set("商品");
		}
	}
}

//定义消费者类Customer,消费商品
class Customer implements Runnable{
	private Resource r;
	Customer(Resource r){
		this.r = r;
	}
	public void run(){
		while(true){
			r.show();
		}
	}
}

分析:

  • 多个生产者、消费者定义使用while判断标记

    原因:让被唤醒的线程再次判断标记

  • 定义中使用notifyAll

    原因: 因为需要唤醒对方线程,如果使用notify容易出现值唤醒本方线程的情况,导致线程中所有线程都处于等待状态

2.JDK5中提供多线程解决方案

  • 将同步synchronized替换成lock操作
  • 将object中的wait/notify/notifyALl替换成condtion对象
  • 该对象可以通过lock锁进行获取

示例:

package unit18;

import java.util.concurrent.locks.*;

class Resources{
	private String name;
	private int count = 1;
	private Boolean flag = false;

	private Lock lock = new ReentrantLock();//定义Lock类

	private Condition condition_pro = lock.newCondition();
	private Condition condition_con = lock.newCondition();

	public  void set(String name)throws InterruptedException{
		lock.lock();//添加锁
		try{
		while(flag){
			condition_pro.wait();//生产者调用线程等待
		  }
		this.name = name+"__ " + count++;
		System.out.println(Thread.currentThread().getName()+ "......生产者" + this.name);
		flag = true;
		condition_pro.signal();	//唤醒消费者线程
		}catch(Exception e){}
		finally{
			lock.unlock();//解锁
		}
	}

	public synchronized void show()throws InterruptedException{
		lock.lock();
		try{
		while(!flag){
			condition_con.wait();
		}

		System.out.println(Thread.currentThread().getName()+"消费者"+ this.name);
		flag = false;
		condition_con.signal();//唤醒生产者线程
		}catch(Exception e){}
		finally{
			lock.unlock();
		}
	}
}

class Producters implements Runnable{
	private Resources r;
	Producters(Resources r){
		this.r = r;
	}
	public void run(){
		while(true){
			try {
				r.set("商品");
			} catch (InterruptedException e) {

			}
		}
	}
}

class Customers implements Runnable{
	private Resources r;
	Customers(Resources r){
		this.r = r;
	}
	public void run(){
		while(true){
			try {
				r.show();
			} catch (InterruptedException e) {

			}
		}
	}
}

public class ProducterCustomerTest2 {

	public static void main(String[] args) {
		Resources r = new Resources();
		Producters pro = new Producters(r);
		Customers cus = new Customers(r);
		Thread t1 = new Thread(pro);
//		Thread t2 = new Thread(pro);
//		Thread t3 = new Thread(cus);
		Thread t2 = new Thread(cus);
		t1.start();
//		t2.start();
//		t3.start();
		t2.start();
	}

}

  

时间: 2024-10-03 21:53:38

生产者--消费者模式的相关文章

阻塞队列和生产者-消费者模式

阻塞队列提供了可阻塞的put和take方法.如果队列满了put将阻塞到有空间可用,如果队列为空,take将阻塞到有元素可用.队列可以是有界和无界的,无界的队列put将不会阻塞. 阻塞队列支持生产者消费者模式,该模式将找出需要完成的工作,和执行工作分开.生产者-消费者模式能简化开发过程,因为消除了生产者和消费者之间的代码依赖性,此外,该模式还将生产数据的过程和使用数据的过程解耦开来. 在基于阻塞队列构建的生产者-消费者设计中个,当数据生成时,生产者把数据放入队列,当消费者处理数据时,将从队列中获取

并发编程基础之生产者消费者模式

一:概念 生产者消费者模式是java并发编程中很经典的并发情况,首先有一个大的容器,生产者put元素到 容器中,消费者take元素出来,如果元素的数量超过容器的容量时,生产者不能再往容器中put元素 ,处于阻塞状态,如果元素的数量等于0,则消费者不能在从容器中take数据,处于阻塞状态. 二:示例 /** * */ package com.hlcui.main; import java.util.LinkedList; import java.util.concurrent.ExecutorSe

生产者消费者模式

什么是生产者消费者模式   在工作中,大家可能会碰到这样一种情况:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产者:而处理数据的模块,就称为消费者.在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式.结构图如下: 生产者消费者模式的优点 1.解耦 假设生产者和消费者分别是两个类.如果让生产者直接调用消费者的某个方法,那

使用BlockingQueue的生产者消费者模式

BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出:在生产者消费者模式中,通过队列的方式可以很方便的实现两者之间的数据共享.强大的BlockingQueue使我们不用关心什么时候需要阻塞线程,什么时候需要唤醒线程. BlockingQueue的

生产者消费者模式(转)

本文转载自博文系列架构设计:生产者/消费者模式.文中对原文格式进行了稍加整理. 概述 今天打算来介绍一下“生产者/消费者模式”,这玩意儿在很多开发领域都能派上用场.由于该模式很重要,打算分几个帖子来介绍.今天这个帖子先来扫盲一把.如果你对这个模式已经比较了解,请跳过本扫盲帖,直接看下一个帖子(关于该模式的具体应用) . 看到这里,可能有同学心中犯嘀咕了:在四人帮(GOF)的23种模式里面似乎没听说过这种嘛!其实GOF那经典的23种模式主要是基于OO的(从书名<Design Patterns: E

生产者消费者模式(吃包子例子)

生产者-消费者问题是一个经典的进程同步问 题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制.在同一个进程地址空间内执行的两个线程生产者线程生产物品,然后将物品放置在一个空 缓冲区中供消费者线程消费.消费者线程从缓冲区中获得物品,然后释放缓冲区.当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费 者线程释放出一个空缓冲区.当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来. 生产者消费者模式是并发.多线程编程中经典的设计

Java 并发编程(四)阻塞队列和生产者-消费者模式

阻塞队列 阻塞队列提供了可阻塞的 put 和 take 方法,以及支持定时的 offer 和 poll 方法.如果队列已经满了,那么put方法将阻塞直到有空间可以用:如果队列为空,那么take方法将一直阻塞直到有元素可用.队列可以使有界的,也可以是无界的,无界队列永远都不会充满,因此无界队列上的put方法永远不会阻塞.一种常见的阻塞生产者-消费者模式就是线程池与工作队列的组合,在 Executor 任务执行框架中就体现了这种模式. 意义:该模式能简化开发过程,因为他消除了生产者和消费者类之间的代

关于java中生产者消费者模式的理解

在说生产者消费者模式之前,我觉得有必要理解一下 Obj.wait(),与Obj.notify()方法.wait()方法是指在持有对象锁的线程调用此方法时,会释放对象锁,同时休眠本线程.notify()方法是持有相同的对象锁来唤醒休眠的线程,使其具有抢占cpu的资格.可以理解同步方法,同步方法的对象锁就是谁调用这个方法,这个对象就是对象锁. 根据李兴华老师的视频讲解,建立一个生产者类,一个消费者类,还有一个Info类,贴上代码: 1.生产者类 package com.company; /** *

python 多线程笔记(6)-- 生产者/消费者模式(续)

用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import random products = 20 class Producer(threading.Thread): '''生产者''' ix = [0] # 生产者实例个数 # 闭包,必须是数组,不能直接 ix = 0 def __init__(self): super().__init__() sel

生产者消费者模式下的并发无锁环形缓冲区

上一篇记录了几种环形缓冲区的设计方法和环形缓冲区在生产者消费者模式下的使用(并发有锁),这一篇主要看看怎么实现并发无锁. 0.简单的说明 首先对环形缓冲区做下说明: 环形缓冲区使用改进的数组版本,缓冲区容量为2的幂 缓冲区满阻塞生产者,消费者进行消费后,缓冲区又有可用资源,由消费者唤醒生产者 缓冲区空阻塞消费者,生产者进程生产后,缓冲区又有可用资源,由生产者唤醒消费者 然后对涉及到的几个技术做下说明: ⑴CAS,Compare & Set,X86下对应的是CMPXCHG 汇编指令,原子操作,基本