zoukankan      html  css  js  c++  java
  • java中使用阻塞队列实现生产这与消费这之间的关系

    需求如下:

      有一个生产者和一个消费者,生产者不断的生产产品,消费这不断的消费产品.产品总数为N.

      1.生产顺序按队列的方式,先进先出.

      2.生产者和消费这可以同时进行.

      3.当生产者生产了N个产品后不能继续生产,消费者消费完后不能继续消费.

      4.当生产完成,或者消费完成时,要节约CPU开支(不能使用Sleep);

      5.尽量少定义变量,高效率实现.

    说明:花了一个小时实现的,如果有不同的意见,希望大家能够指出,共同学习共同进步.

    下面说一下我分析的过程:

      题目上说:

        1.有一个生产者和消费者,这个告诉我们至少要建立两个线程,一个生产者线程,一个消费者线程

        2.由生产顺序:先进先出,告诉我们应该使用一个队列.

        3.生产和消费可以同时进行:告诉我们至少我们应该考虑并发的问题,我正在生产时你别来消费.

        4.要节约CPU开支和生产,消费完成后不能继续生产或者消费:告诉我们而且不能使用Sleep,那么我们应该想到的是,使用wait或者阻塞队列.

    抽象一下模型:创建两个线程,一个用于不断的向集合中添加数据,一个不断的向集合中取除数据,如果集合已满,则进行阻塞,如果取数据是集合为空则仍然进行阻塞.

    好了下面贴出源代码,如果中间有什么不明白的大家可以查看java jdk帮助文档,上面都有介绍,我这里就不再说了.

    生产者:

    package cn.yw.daydayinterviewquestion;
    
    import java.util.concurrent.ArrayBlockingQueue;
    
    public class MainTest {
        /**
         * 程序的入口main方法
         * 
         * @param args
         */
        public static void main(String[] args) {
            final WorkShop workShop = new WorkShop();
            // production
            new Thread() {
                public void run() {
                    while(true){
                        try {
                            workShop.production();
                            Thread.sleep(100);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
            }.start();
            // customer
            new Thread() {
                public void run() {
                    while(true){
                        try {
                            workShop.customer();
                            Thread.sleep(100);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };
            }.start();
        }
    
        /**
         * 车间类
         * 
         * @author yw-tony
         * 
         */
        static class WorkShop {
            private int i = 0;
            private int countNum = 100;//产品总量
            // 产品队列
            ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1);
            //加上互斥技术以防止生产者生产到一半时消费这就消费了.
            // 生产方法
            public synchronized void production() throws Exception{
                if (i < countNum) {
                    i++;
                    /*System.out.println("线程" + Thread.currentThread().getName()
                            + "准备生产产品." + i);*/
                    queue.put(i);
                    System.out.println("线程" + Thread.currentThread().getName()
                            + "生产了产品." + i);
                }else{
                    System.out.println("生产完成,等待中....");
                    queue.take();
                }
                
            }
    
            // 消费方法
            public synchronized void customer() throws Exception{
                /*countNum--;
                System.out.println("准备消费产品"+countNum);*/
                //消费完成的依据是,消费数等于产品数
                Integer c = queue.take();//检索并移除此队列的头部,如果次队列为空,这一直处于等待状态.
                System.out.println("消费了产品"+c);
                if(c >= 100){
                    System.out.println("消费完成,正在等待商品产出.....");
                }
            }
    
        }
    }

    备注:在这里不用阻塞队列也是可以的,使用线程之间的通信技术一样能够实现,有兴趣的朋友可以写一下,我这里就不写了.

       

  • 相关阅读:
    Android中文API(119)——TableRow
    Android开发者指南(12) —— Android Supported Media Formats
    Android中文合集 最终版
    Android开发者指南(10) —— Android API Levels
    Android中文API(126) —— Message
    Android中文API(118)——FilterQueryProvider
    [Android]通过PhoneLookup读取所有电话号码
    Android中文API(124) —— DialerFilter
    Android开发者指南(15) —— Managing Virtual Devices
    Android中文API(127) —— MessageQueue
  • 原文地址:https://www.cnblogs.com/tony-yang-flutter/p/3603688.html
Copyright © 2011-2022 走看看