生产者消费者模式的三种实现方式

synchronized版本

public class Test {
	public static void main(String[] args) {

		Shared s = new Shared();
		Thread t1 = new Thread(new Product(s));
		Thread t2 = new Thread(new Consumer(s));
		t1.start();
		t2.start();
	}
}

class Product implements Runnable {

	private final Shared s;
	public Product(Shared s) {
		this.s = s;
	}
	@Override
	public void run() {
		for (char i = 'A'; i < 'Z'; i++) {
			s.setChar(i);
			System.out.println("生产者生产了一个" + i);
		}
	}
}

class Consumer implements Runnable {

	private final Shared s;
	public Consumer(Shared s) {
		this.s = s;
	}
	@Override
	public void run() {
		char c;
		do{
			c = s.getChar();
			System.out.println("消费者消费了一个" + c);
		} while(c!='Y');
	}
}

class Shared {

	private char ch;
	private volatile boolean writeable = true;
	public synchronized char getChar() {
		while(writeable) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		writeable = true;
		notify();
		return ch;
	}

	public synchronized void setChar(char ch) {
		while(!writeable) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		writeable = false;
		this.ch = ch;
		notify();
	}
}

ReentrantLock版本

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Test1 {

	public static void main(String[] args) {
		Shared1 s = new Shared1();
		Thread t1 = new Thread(new Product1(s));
		Thread t2 = new Thread(new Consumer1(s));
		t1.start();
		t2.start();
	}
}

class Shared1 {
	private char c;
	private volatile boolean writeable = true;
	private final ReentrantLock lock = new ReentrantLock();
	private final Condition condition = lock.newCondition();

	public void setChar(char c) {
		lock.lock();
		try {
			while (!writeable) {
				try {
					condition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			writeable = false;
			condition.signal();
			this.c = c;
		} finally {
			lock.unlock();
		}
	}

	public char getChar() {
		lock.lock();
		try {
			while(writeable) {
				try {
					condition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			writeable = true;
			condition.signal();
			return c;
		} finally {
			lock.unlock();
		}
	}
}
class Product1 implements Runnable {
	private Shared1 s;
	public Product1(Shared1 s) {
		this.s = s;
	}
	@Override
	public void run() {
		for (char i = 'A'; i < 'Z'; i++) {
			s.setChar(i);
			System.out.println("生产者生产了一个" + i);
		}
	}

}
class Consumer1 implements Runnable {
	private Shared1 s;
	public Consumer1(Shared1 s) {
		this.s = s;
	}
	@Override
	public void run() {
		char c;
		do{
			c = s.getChar();
			System.out.println("消费者消费了一个" + c);
		} while(c != 'Y');
	}
}

使用阻塞队列实现的版本

import java.util.concurrent.ArrayBlockingQueue;

public class MyBlockArray {

	public static final ArrayBlockingQueue<Character> arr = new ArrayBlockingQueue<>(26);
	public static void main(String[] args) {
		final MyBlockArray my = new MyBlockArray();
		Thread t1 = new Thread(new Product3(my));
		Thread t2 = new Thread(new Consumer3(my));
		t1.start();
		t2.start();
	}
}

class Product3 implements Runnable {
	private MyBlockArray blockArray;
	public Product3(MyBlockArray blockArray) {
		this.blockArray = blockArray;
	}
	@Override
	public void run() {
		for (char i = 'A'; i <= 'Z'; i++) {
			try {
				blockArray.arr.put(i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("生产者生产了一个" + i);
		}
	}

}
class Consumer3 implements Runnable {
	private MyBlockArray blockArray;
	public Consumer3(MyBlockArray blockArray) {
		this.blockArray = blockArray;
	}
	@Override
	public void run() {
		char c = 0;
		do {
			try {
				c = blockArray.arr.take();
				System.out.println("消费者消费了一个" + c);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} while(c != 'Z');
	}
}

原文地址:http://blog.51cto.com/12222886/2070355

时间: 2024-08-14 04:22:05

生产者消费者模式的三种实现方式的相关文章

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

   1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理, 直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力.这个阻塞队列就是用来给生产者和消费者解耦的. 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度

生产者/消费者模式(三)

上篇文章尝试着使用head lock和tail lock分别在Get和Add元素时,对队列进行上锁,这样就避免了每次操作都锁住整个队列,缩小了锁的粒度.这里还有个问题,队列中持有的T对象指针,均是由调用者动态分配和释放的,如果调用量特别大,new/delete操作频繁,同样会导致性能下降,可能使系统产生大量的内存碎片.对于这个问题,我最开始想到的是让队列中不持有原生指针,而是使用带引用计数的智能指针,但后来想想,这样只可能避免内存泄露和赋值拷贝时大量内存复制的情况,而队列中元素只有存取两种行为,

java 多线程并发系列之 生产者消费者模式的两种实现

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这种生产消费能力不均衡的问题,所以便有了生产者和消费者模式. 什么是生

生产者消费者问题Java三种实现

生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/消费者问题的方法可分为两类: 采用某种机制保护生产者和消费者之间的同步: 在生产者和消费者之间建立一个管道. 第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式.第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强. 在Java中有四种方法支持同步,其中前三个是同步

关于生产者与消费者模式的两种实现方式

1.wait & notify 方法: public class WaitAndNotify { private final int MAX_SIZE = 100; private LinkedList<Object> list = new LinkedList<Object>(); public void produce(int num) { synchronized (list) { while (list.size() + num > MAX_SIZE) { S

使用管程实现生产者消费者模式

生产者消费者模式是一种常见的设计模式,掌握一种完美,稳定的实现方式非常有用,下面我就使用misa管程实现生产者消费者模式. 这种实现的优点: 1.稳定,不会出现死锁现象 2.运行速度相对较快 话不多说,直接上代码: 管程类: package com.brave.test; import java.util.ArrayList; import java.util.List; /** * * @描述:管程区 * * @author <p>[email protected]<p> bra

生产者消费者模式的java实现(实现一)

在多线程以及并发工具类中,常用的一种思想就是生产者消费者模式,生产者负责生产物品,将物品放到传送带,消费者负责获取传送带的物品,消费物品.现在只考虑最简单的情况,传送带上只允许放一个物品. 1.传送带为空,则允许生产者放置物品,否则不许放(生产者线程wait). 2.生产者放置完物品后,通知消费者可以拿了(线程通信,notify 或者notifyAll). 2.传送带不空,则允许消费者拿物品,否则不许拿(消费者线程wait). 3.消费者拿走物品后,通知生产者可以继续生产(线程通信,notify

cookie 和 session的区别 &amp; 三种传值方式

1.session保存在服务器,客户端不知道其中的信息:cookie保存在客户端,服务器能够知道其中的信息. 2.session中保存的是对象,cookie中保存的是字符串. 3.session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到.而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的. 4.session以cookie为基础,session需要借助cookie才能正常工作,如果客户端完全禁止cookie

canvas入门-1三种填充方式、渐变、模式

1.定义canvas的尺寸的时候最好用html的方式定义,用width和height的方式,用css会导致画布按照css设定的方式进行缩放,cavas内部是一个2d的渲染环境 2.一个canvas对应一个2d的渲染环境,绘制图形的操作都是在2d渲染环境中进行的 <canvas id="canvas-1" style="border:solid 1px gray;" width = "400" height="400"&g