前言
生产者-消费者模式是一个经典的多线程设计模式,它为多线程的协作提供了良好的解决方案。在生产者-消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程负责处理用户请求。生产者和消费者之间通过共享内存缓冲区进行通信。
生产者-消费者模式中的内存缓冲区的主要功能是数据在多线程间的共享。此外,通过该缓冲区,可以缓解生产者和消费者之间的性能差。
Android虽然是个单线程模型的系统,但是为了在程序开发的实践当中,为了让程序表现得更加流畅,我们肯定会需要使用到多线程来提升程序的并发执行性能,但是编写多线程并发的代码一直以来都是一个相对棘手的问题,所以想要获得更佳的程序性能,我们非常有必要掌握多线程并发编程的基础技能。这里我们先来了解下生产者与消费者模式:
实现方式一:****wait() 和 notify() 通信方法实现
public class ThreadTest1 {
//产品
static class ProductObject{
//线程操作变量可见 一定要加
public volatile static String value;
}
//生产者线程
static class Producer extends Thread{
Object lock;
public Producer(Object lock) {
this.lock = lock;
}
@Override
public void run() {
//不断生产产品
while(true){
synchronized (lock) { //互斥锁
//产品还没有被消费,等待
if(ProductObject.value != null){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//产品已经消费完成,生产新的产品
ProductObject.value = "NO:"+System.currentTimeMillis();
System.out.println("生产产品:"+ProductObject.value);
lock.notify(); //生产完成,通知消费者消费
}
}
}
}
//消费者线程
static class Consumer extends Thread{
Object lock;
public Consumer(Object lock) {
this.lock = lock;
}
@Override
public void run() {
while(true){
synchronized (lock) {
//没有产品可以消费
if(ProductObject.value == null){
//等待,阻塞
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费产品:"+ProductObject.value);
ProductObject.value = null;
lock.notify(); //消费完成,通知生产者,继续生产
}
}
}
}
public static void main(String[] args) {
Object lock = new Object();
new Producer(lock).start();
new Consumer(lock).start();
}
}
实现方式二:*采用阻塞队列实现生产者消费者模式*
阻塞队列实现生产者消费者模式超级简单,它提供开箱即用支持阻塞的方法put()和take(),开发者不需要写困惑的wait-nofity代码去实现通信。BlockingQueue 一个接口,Java5提供了不同的现实,如ArrayBlockingQueue和LinkedBlockingQueue,两者都是先进先出(FIFO)顺序。而ArrayLinkedQueue是自然有界的,LinkedBlockingQueue可选的边界。下面这是一个完整的生产者消费者代码例子,对比传统的wait、nofity代码,它更易于理解。
public class ConsumerQueue implements Runnable {
private final BlockingQueue conQueue;
public ConsumerQueue(BlockingQueue conQueue) {
this.conQueue = conQueue;
}
@Override
public void run() {
for (;;)
{
try {
System.out.println("消费者消费的苹果编号为 :" +conQueue.take());
// Thread. sleep(3000); //在这里sleep是为了看的更加清楚些
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
public class ProducerQueue implements Runnable{
private final BlockingQueue proQueue;
public ProducerQueue(BlockingQueue proQueue) {
this.proQueue = proQueue;
}
int i = 0;
@Override
public void run() {
for (;i<20;i++)
{
try {
System. out .println("生产者生产的苹果编号为 : " +i); //放入十个苹果编号 为1到10
proQueue.put(i);
/*Thread.sleep(3000);*/
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
BlockingQueue publicBoxQueue = new LinkedBlockingQueue(2); // 定义了一个大小为1的盒子
Thread con = new Thread(new ConsumerQueue(publicBoxQueue));
Thread pro = new Thread(new ProducerQueue(publicBoxQueue));
pro.start();
con.start();
}
生产者消费者模式的好处
它的确是一种实用的设计模式,常用于编写多线程或并发代码。下面是它的一些优点:
它简化的开发,你可以独立地或并发的编写消费者和生产者,它仅仅只需知道共享对象是谁
生产者不需要知道谁是消费者或者有多少消费者,对消费者来说也是一样
生产者和消费者可以以不同的速度执行
分离的消费者和生产者在功能上能写出更简洁、可读、易维护的代码。
參考文章:
http://blog.csdn.net/yujin753/article/details/45723175