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

前言

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值