其实生产者和消费者模式概念很简单,就是生产者将生产出来的产品放在仓库里,然后消费者依次从仓库里取产品消费。归到程序里,这里的仓库就可以用数组,队列或栈来表示。
掌握以下两点后,该模式的实现将不成问题。
1. 首先要明白生产者和消费者之间的并发对象就是存放产品的队列,这样才能把并发方法提炼出来。
2. 其次要掌握object.wait()和object.notifyAll()这两个方法的基本使用模式:
synchronized (object) {
//条件不成立时,则等待
while(条件不成立){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//需要同步的代码
object.notifyAll();
}
示例1:使用LinkedList实现的FIFO方式的生产者和消费者模式,若要改为先进后出的栈方式,只需把(1)处得注释打开,替换上一语句即可。
package productor.consumer.demo.self;
import java.util.LinkedList;
public class ProductorConsumerDemo {
public static void main(String[] args) {
Queue<IPhone> queue = new Queue<IPhone>();
new Thread(new Productor("生产者1" , queue)).start();
new Thread(new Consumer("消费者1" , queue)).start();
}
}
class IPhone{
private int id;
private String name;
public IPhone(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "{id:" + id + ",name=" + name + "}";
}
}
//FIFO队列
class Queue<T>{
private static final int DEFAULT_SIZE = 8; //定义队列的默认大小
int size ; //定义队列的大小
private LinkedList<T> list = new LinkedList<T>();
public Queue() {
super();
this.size = DEFAULT_SIZE;
}
public Queue(int size) {
super();
this.size = (size <=0 ? DEFAULT_SIZE : size);
}
public synchronized void put(T t){
while(list.size() >= size){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.addLast(t);
System.out.println("生产了:" + t);
this.notifyAll();
}
public synchronized T get(){
while(list.size() <= 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
T t = list.removeFirst();
//先进后出--同栈 t = list.removeLast(); ----(1)
System.out.println("消费了:" + t);
return t;//FIFO
}
}
//生产者
class Productor implements Runnable{
private String name;
private Queue queue;
public Productor(String name,Queue queue) {
super();
this.name = name;
this.queue = queue;
}
@Override
public void run() {
for(int i=0;i<10;i++){
IPhone iPhone = new IPhone(i,"name-" + i);
queue.put(iPhone);
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable{
private String name;
private Queue queue;
public Consumer(String name,Queue queue) {
super();
this.name = name;
this.queue = queue;
}
@Override
public void run() {
for(int i=0;i<10;i++){
IPhone iPhone = (IPhone) queue.get();
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
分享到:
相关推荐
生产者消费者详解wait():执行该方法的线程对象,释放同步锁,JVM会把该线程放到等待池中,等待其他线程唤醒该线程 notify():执行该方法的线程唤醒在等待池中等待的任意一个线程,把线程转到锁池中等待(注意锁池和...
面试高级开发的期间整理的面试题目,记录我面试遇到过的并发题目以及答案 目录 并发 常说的并发问题是哪些;资源竞争、死锁、事务、可见性 ...实现一个阻塞队列(用Condition写生产者与消费者就)?BlockingQueue
25 3:ServicorTo 和 ServicorFrom 互换................................................................................................................25 2.3.3.1. 2.4.1. 如何确定垃圾 ......................
Sybase ASE 15.7 开发文档:...监控协调事务和参与者 .......... 179 DTM 管理和故障排除 .......... 179 事务和控制线程 .......... 179 获取有关分布式事务的信息 .......... 181 执行外部事务的步骤 .......... 185...
这种机制是轻量级的,它使用server端的servlet连接管理、线程工具、javax.servlet API,并通过标准Java特性中Object的wait()和notify()实现的生产者/消费者机制。原则上,Pushlet框架能够运行在任何支持servlet的...
实现了常见的并发题目,包括死锁,互斥示例,阻塞队列,生产者消费者等。 2.1:AwaitSignalExample 使用java并发包里面的 ReentrantLock 和 Condition 实现了互斥示例。 2.2: WaitNotifyCase 使用object对象自带的...
12.synchronized (生产者和消费) 13.String 和 StringBuffer 14.Serializable 15.MVC (Struts的工作流程) 16.什么是MDA 17.tcp与udp的区别 18.链表与散列表和数组的区别 19.堆和栈的区别 20.ejb的分类及...
NIO(通道,缓冲区,选择器) Java服务器端开发面试题篇2 thread, start(), run() 多线程里面的关键字,wait, notfiy, 锁(synchronized), lock接口 线程状态,上下文切换,守护线程 消费者和生产者的几种实现方式,...
16.4.5 “生产者-消费者”案例的实际运行 365 16.4.6 notify方法的使用 366 16.4.7 同步的语句块 367 16.4.8 线程的死锁 369 16.4.9 防止错误的使用wait、notify、notifyAll方法 371 16.5 获取当前正在...
Putting a great looking site together takes a lot of work, and most Java developers are more interested in creating a great looking object interface than a user interface. JavaServer Pages (JSP) ...
一个Oracle Applications DBA(Oracle应用程序数据库管理员)不仅需要和其他DBA一样去负责managing、 sizing、maintaining和 tuning database这些日常的数据库管理的工作,如果他的Apps...,他还需要监察wait和lock ...