多线程之生产者与消费者模式

来源:互联网 发布:java file 相对路径 编辑:程序博客网 时间:2024/05/17 04:48

前言

       生产者-消费者模式是一个经典的多线程设计模式,它为多线程的协作提供了良好的解决方案。在生产者-消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程负责处理用户请求。生产者和消费者之间通过共享内存缓冲区进行通信。
       生产者-消费者模式中的内存缓冲区的主要功能是数据在多线程间的共享。此外,通过该缓冲区,可以缓解生产者和消费者之间的性能差。
       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

0 0
原创粉丝点击