Java实现生产者消费者
方法1:最简单--利用LinkedBlockingQueue
队列具有先进先出的特点,成为经常应用于生产-消费者模式的数据结构。
1.将一个对象放到队列尾部,如果队列已满,就等待直到有空闲节点。 ——put()方法
2.从队列头部取一个对象,如果没有对象,就等待直到有对象可取。 ——take()方法
3.在存取队列的过程中,锁定队列对象,不允许其它线程访问队列。——使得它是线程安全的
下面的代码适用于多个生产者、多个消费者。
//Producer.java
import java.util.concurrent.BlockingQueue; /*
* Usage example, based on a typical producer-consumer scenario.
* Note that a <tt>BlockingQueue</tt> can safely be used with multiple
* producers and multiple consumers.
* <pre>
*/
class Producer implements Runnable {
private BlockingQueue<Object> queue; Producer(BlockingQueue<Object> q) {
queue = q;
} public void run() {
try {
while (true) {
queue.put(produce());
Thread.sleep(1);
System.out.println("+1 Produce an Object:" + "生产者size:"
+ queue.size());
}
} catch (InterruptedException ex) {
System.out.println("生产者结束!");
}
} Object produce() {
return new Object();
}
}
Pruducer.java
//Consumer.java
import java.util.concurrent.BlockingQueue; class Consumer implements Runnable {
private BlockingQueue<Object> queue; Consumer(BlockingQueue<Object> q) {
queue = q;
} public void run() {
try {
while (true) {
consume(queue.take());
Thread.sleep(10);
System.out.println("-1 Consumer an Object:" + "size:"+ queue.size());
}
} catch (InterruptedException ex) {
System.out.println("消费者结束!");
}
} void consume(Object x) {
}
}
Consumer.java
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; class Main {
public static void main(String[] args) {
BlockingQueue<Object> q = new LinkedBlockingQueue<Object>();// SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
Thread pth = new Thread(p);
pth.start();
new Thread(c1).start();
new Thread(c2).start();
try {
Thread.sleep(50);
pth.interrupt();
} catch (InterruptedException e) {
}
}
}
Main.java
方法2:不采用BlockingQueue,利用lock、Condition来实现
思路:
利用可重用的LinkedList来存放资源,生产者addLast(),消费者removeFirst()。
使用ReentrantLock()来实现消费者和生产者的同步;//可重用的互斥锁
思考:为什么使用了lock后,还使用了它的2个newCondition,这样做有什么好处?
import java.util.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class ProducerConsumer {
private static final LinkedList<Integer> buffer = new LinkedList<Integer>();
private static final int BUFFERSIZE = 10;
private static Lock lock = new ReentrantLock();//可重用的互斥锁
private static Condition NotFull = lock.newCondition();
private static Condition NotEmpty = lock.newCondition(); static class Producer extends Thread {
public void run() {
while (true) {
// lock
lock.lock();
if (buffer.size() == BUFFERSIZE) {
System.out.println("BUffer is fulls");
try {
NotFull.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
buffer.addLast(1);
NotEmpty.signal();
}
lock.unlock();
// unlock
}
}
} static class Consumer extends Thread {
public void run() {
while (true) {
// lock
lock.lock();
if (buffer.size() == 0) {
System.out.println("BUffer is empty");
try {
NotEmpty.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
buffer.removeFirst();
NotFull.signal();
}
// unlock
lock.unlock();
}
}
} public static void main(String[] args){
new Consumer().start();
new Producer().start();
}
}
ProducerConsumer .java
关于Java线程的lock、condition、synchronized的小小总结:
1.synchronized简单易用,但是功能受局限,无法满足复杂的同步机制,比如“读者写者问题”:多个读者线程是不互斥的。
2.lock以更优雅的方式来解决线程同步,比如读写锁ReadWriteLock。
3.Condition解决线程间通信,为不同的线程建立不同的条件。
推荐博文:Java线程-锁机制
Condition可以替代传统的线程间通信,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll()。
——为什么方法名不直接叫wait()/notify()/nofityAll()?因为Object的这几个方法是final的,不可重写!
Condition实现了BlockingQueue的功能。
看看BlockingQueue的继承和实现。
一般的锁Lock的实现:注意ReadLock、WriteLock是内部的静态类,只有ReentrantReadWriteLock类可以调用。
读写的锁ReadWriteLock
思考:OS的信号量是什么,线程通信的方式有哪些?共享变量和消息传递。
信号量与互斥锁有什么联系?
By BYRHuangQiang2014-03-18 09:05:30
Java实现生产者消费者的更多相关文章
- Java实现生产者消费者问题与读者写者问题
摘要: Java实现生产者消费者问题与读者写者问题 1.生产者消费者问题 生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从 ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- java实现生产者消费者问题
引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...
- java实现生产者消费者问题(转)
引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,如下图所示,生产者向空间里存放数据,而消费者取用数据,如果不加以协调可能会出现以下情况: 生产者消费者图 ...
- [转载] Java实现生产者消费者问题
转载自http://www.cnblogs.com/happyPawpaw/archive/2013/01/18/2865957.html 引言 生产者和消费者问题是线程模型中的经典问题:生产者和消费 ...
- java实现生产者消费者模式
生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个具有多个缓冲区的缓冲池,生产者将 ...
- java 线程 生产者-消费者与队列,任务间使用管道进行输入、输出 解说演示样例 --thinking java4
package org.rui.thread.block2; import java.io.BufferedReader; import java.io.IOException; import jav ...
- Java 实现生产者 – 消费者模型
转自:http://www.importnew.com/27063.html 考查Java的并发编程时,手写“生产者-消费者模型”是一个经典问题.有如下几个考点: 对Java并发模型的理解 对Java ...
- Java——Java实现生产者消费者
1.生产/消费者模型 生产/消费者问题是个非常典型的多线程问题,涉及到的对象包括"生产者"."消费者"."仓库"和"产品" ...
- java多线程 生产者消费者模式
package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...
随机推荐
- Java泛型方法定义及泛型类型推断
泛型的推断 @Test public void test3(){ //类型推断时使用两个类型的最小公倍数 int x1 = add(3,4); Number x2 = add(3.5,4); Obje ...
- Java基础知识强化之集合框架笔记48:产生10个1~20之间的随机数(要求:随机数不能重复) 简洁版
1. 编写一个程序,获取10个1至20的随机数,要求随机数不能重复. 分析: A: 创建随机数对象 B: 创建一个HashSet集合 C: 判断集合的长度是不是小于10 是:就创建一个随机 ...
- ubuntu15.10英文系统中文输入法配置 fcitx
15.10 默认安装的输入法engine就是fcitx,如果你安装的时候locale选中文,应该不用任何折腾就可以用了,但我习惯了用英文系统,所以..... 系统安装好之后,做如下修改: 安装语言包 ...
- JavaScript 是世界上最好的语言?
2016年1月中旬,Stack Overflow发起本年度的开发者调查,调查结果于近日公布.本文盘点 JS 开发者应该会关心的部分数据. Stack Overflow 技术排行榜: 在2015年6月, ...
- NoteExpress格式化复制指定输出样式
在NoteExpress中没有看到为命令“选中的题录右击 => 复制题录 => 格式化复制”指定输出样式的明确配置项,但格式化复制的输出样式也是可以变化了,随细节大面板里的“预览”标签页里 ...
- angularjs 更新局部作用域
前几天项目需要,做了一个背景遮罩的弹出框,html采用js动态添加进去的,结果发现angularjs绑定在这里面不起作用,搜索下解决了,记录下: var smallApplyParent = docu ...
- jquery easyui动态校验,easyui动态验证
>>>>>>>>>>>>>>>>>>>>>>>>> ...
- quartz.net 基于数据库的简单实现
前面简单学习了通过XML配置或者内存指定的方式实现调度任务.但此用法实战用途较小,企业上多需要分布式集群的方式.quart团队也考虑到了这点,于是有了我们今天要学习的.基于数据库实现分布式. Name ...
- Android多屏幕适配
转载:http://mikewang.blog.51cto.com/3826268/865304 问题: 测试时,发现应用在不同的显示器上显示效果不同(部分文本不能显示完全),自然想到屏幕适配的问题. ...
- P2P之UDP穿透NAT原理
首先先介绍一些基本概念: NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就 ...