Java 生产者模式 消费者模式
// The standard idiom for calling the wait
synchronized(sharedObject) {
while(condition){
sharedObject.wait();// Releases lock, and reacquires on wake up
}
// do action based upon condition e.g. take or put into queue
}
使用wait和notify函数的规范代码模版。
在while循环里使用wait的目的:是在线程被唤醒前后都持续检查条件是否被满足,如果条件并未改变,wait被调用之前notify的唤醒通知就来了,那个这个线程并不能保证被唤醒,有坑会导致死锁的问题。
public class ProducerConsumer {
public static void main (String args[]) {
Queue<Integer> buffer = new LinkedList<>();
int maxSize = 10;
Thread producer = new Producer(buffer, maxSize, "PRODUCER");
Thread consumer = new Producer(buffer, maxSize, "CONSUMER");
producer.start();
consumer.start();
}
}
在上面代码中,声明了一个LinkedList作为缓冲区队列(在java中,LinkedList实现了队列的接口)。
class Producer extends Thread {
private Queue<Integer> queue;
private int maxSize;
public Producer(Queue<Integer> queue, int maxSize, String name) {
super(name);
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run () {
while (true) {
synchronized (queue) { // 其它线程不能在我们检查条件时改变这个队列
while (queue.size() == maxSize) {
try {
// Queue is full
// Producer thread waiting for
// consumer to take something from queue
queue.wait();
} catch (Exception e) {
e.printStackTrace();
}
Random random = new Random();
int producerValue = random.nextInt();
queue.add(producerValue);
queue.notifyAll();
}
}
}
}
}
如上代码为生产者,其在无限循环中持续往LinkedList里插入随机整数直到LinkedList满。如果队列满了,那么生产者线程会在消费者线程消耗掉队列里的任意一个整数,并用notify通知生产者线程之前持续等待。
class Consumer extends Thread {
private Queue<Integer> queue;
private int maxSize;
public Consumer (Queue<Integer> queue, int maxSize, String name ){
super(name);
this.queue = queue;
this.maxSize= maxSize;
}
@Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
// queue is empty;
// Consumer thread is waiting
// for producer thread to put something in queue
try {
queue.wait();
} catch (Exception e) {
e.printStackTrace();
}
print("Consumer value : " + queue remove());
queue.notifyAll();
}
}
}
}
}
注意:
1. 你可以使用wait和notify函数来实现线程间通信,你可以用它们来实现多线程之间的通信。
2. 永远在synchronized的函数或者对象里使用wait、notify、notifyAll,不然java虚拟机会生成IllgalMonitorStateException。
3. 永远在while循环里而不是在if语句下使用wait,这样,循环会在线程睡眠前后都检查wait的条件,并在条件实际上并未改变的情况下处理唤醒通知。
4. 永远在多线程间共享的对象(生产者消费者模型里即缓冲区队列)上使用wait。
Producer - Consumer Pattern:
Consumer:
sunchronized (obj) {
while (!workToDo) {
obj.wait();
}
// get next item from this queue
workToDo = false;
}
// do work on the item
Producer:
synchronized (obj) {
if (!workToDo) {
// add work to queue
workToDo = true;
}
obj.notifyAll();
}
Java 生产者模式 消费者模式的更多相关文章
- java生产者与消费者模式
前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...
- Java并发编程(4)--生产者与消费者模式介绍
一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...
- Java多线程设计模式(2)生产者与消费者模式
1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...
- java 线程并发(生产者、消费者模式)
线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...
- java进阶(40)--wait与notify(生产者与消费者模式)
文档目录: 一.概念 二.wait的作用 三.notify的作用 四.生产者消费者模式 五.举例 ---------------------------------------分割线:正文------ ...
- 使用libuv实现生产者和消费者模式
生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...
- condition版生产者与消费者模式
1.简介 在爬虫中,生产者与消费者模式是经常用到的.我能想到的比较好的办法是使用redis或者mongodb数据库构造生产者消费者模型.如果直接起线程进行构造生产者消费者模型,线程容易假死,也难以构造 ...
- 【爬虫】Condition版的生产者和消费者模式
Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...
- 【爬虫】Load版的生产者和消费者模式
''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...
- Java生产者与消费者(上)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 生产与消费者模式,是编程中最常用的模式之一,在多线程中应用比较明显.个人理解:在自助餐厅,厨师在不断 ...
随机推荐
- Linux snmp
http://www.cnblogs.com/amberly/p/4364072.html http://blog.csdn.net/awenluck/article/details/50220221
- Spring Boot的快速启动和部署
>>关于Spring Boot 这是官网描述的特点: 1.Create stand-alone Spring applications 创建独立的Spring应用 2.Embed Tomc ...
- 【翻译八】java-内存一致性错误
Memory Consistency Errors Memory consistency errors occur when different threads have inconsistent v ...
- 《linux系统及其编程》实验课记录(六)
实验 6:Linux 文件系统 实验环境: 安装了 Red Hat Enterprise Linux 6.0 可运行系统,并且是成功验证系统.有另外一个无特权用户 student,密码 student ...
- php计算几分钟前、几小时前等
function format_date($time){ $t=time()-$time; $f=array( '=>'年', '=>'个月', '=>'星期', '=>'天' ...
- 用.NET开发通用Windows App
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:随着Windows 10的正式发布,作为.NET开发人员应该开始或多或少了解一下通用( ...
- loj 1167(二分+最大流)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26881 思路:我们可以二分最大危险度,然后建图,由于每个休息点只能 ...
- 数据分析(4):Scipy
科学计算 最小二乘leastsq # -*- coding: utf-8 -*- def func(x,p): # p 参数列表 A,k,theta = p; # 可以一一对应赋值 return A* ...
- 网页或php服务连不上的几个可能原因
1.webserver未启动. 2.php未启动. 3.url中端口和webserver配置文件中的不一致.
- 【jackson 异常】com.fasterxml.jackson.databind.JsonMappingException异常处理
项目中,父层是Gene.java[基因实体] 子层是Corlib.java[文集库实体],一种基因对用多个文集库文章 但是在查询文集库这个实体的时候报错:[com.fasterxml.jackson ...