LinkedBlockingQueue 实现生产者消费者模型


并发编程栏目代码 GitHub package 地址: 点击打开链接

博客并发编程栏目 : 点击打开链接


实现

LinkedBlockingQueue是一个基于已链接节点的、范围任意的blocking queue的实现。 阻塞队列


    此队列按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。 
    新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列, 
    但是在大多数并发应用程序中,其可预知的性能要低。 
    可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。 
    如果未指定容量,则它等于 Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。 

  1.     如果未指定容量,默认容量为Integer.MAX_VALUE ,容量范围可以在构造方法参数中指定作为防止队列过度扩展。
  2.     此对象是 线程阻塞-安全的   
  3.  不接受 null 元素 
  4.     它实现了BlockingQueue接口。
  5.     实现了 Collection 和 Iterator 接口的所有可选 方法。  


部分方法API


private static void linkedBlockingQueue2Void() {

        LinkedBlockingQueue<String> queue = new LinkedBlockingQueue<String>();
        //将指定元素插入到此队列的尾部(如果立即可行且不会超出此队列的容量),在成功时返回 true,如果此队列已满,则返回 false。
        boolean isOffer = queue.offer("aa");
        queue.offer("ee");

        try {
            // 等待1s
            isOffer = queue.offer("bb", 1000L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            System.out.println("offer(E e, long timeout, TimeUnit unit) run ... 在等待时被中断...");
        }

        //获取但不移除此队列的头;如果此队列为空,则返回 null。
        String head = queue.peek();

        //获取并移除此队列的头,如果此队列为空,则返回 null。
        head = queue.poll();

        try {
            //获取并移除此队列的头部,在指定的等待时间前等待可用的元素(如果有必要)。
            head = queue.poll(1000L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            System.out.println("poll(long timeout, TimeUnit unit) run ... 在等待时被中断...");
        }

        try {
            //TODO 获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。
            queue.take();
        } catch (InterruptedException e) {
            System.out.println("take()  run ... 在等待时被中断...");
        }
        try {
            //将指定元素插入到此队列的尾部,如有必要,则等待空间变得可用。
            queue.put("cc");
        } catch (InterruptedException e) {
            System.out.println("put(E e) run ... 在等待时被中断...");
        }

        //返回理想情况下(没有内存和资源约束)此队列可接受并且不会被阻塞的附加元素数量。
        int remainingCapacity2Size = queue.remainingCapacity();

        //移除元素,如果存在
        queue.remove("dd");

    }


鉴于此队列实现的生产者消费者模型


模拟对象

/**
 * 模拟商品对象
 *
 * @author wei.Li by 14-8-21.
 */
public class CommodityObj {

    private String objId;

    public CommodityObj() {
        this.objId = UUID.randomUUID().toString();
    }

    public String getObjId() {
        return objId;
    }

    public void setObjId(String objId) {
        this.objId = objId;
    }

    @Override
    public String toString() {
        return "Obj{" +
                "objId='" + objId + '\'' +
                '}';
    }
}


生产者 消费者,可以认为 new 一个对象即为一个生产供应商 、消费商

/**
 * 生产者
 *
 * @author wei.Li by 14-8-21.
 */
public class Producer implements Runnable {

    @Override
    public void run() {
        while (MarketStorage.isRun_Cousumer) {
            //随机睡眠
            try {
                Thread.sleep(new Random().nextInt(MarketStorage.PRODUCER_THREAD_SLEEP));

                //生产对象
                CommodityObj commodityObj = new CommodityObj();
                MarketStorage.blockingQueue.put(commodityObj);
                System.out.println(this + " producer obj succeed->" + commodityObj);

                MarketStorage.getProducerObj_Count.getAndIncrement();//计数器++
                System.out.println("getProducerObj_Count is :" + MarketStorage.getProducerObj_Count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}



/**
 * 消费者
 *
 * @author wei.Li by 14-8-21.
 */
public class Consumer implements Runnable {

    @Override
    public void run() {
        while (MarketStorage.isRun_Cousumer) {

            try {
                //随机睡眠
                Thread.sleep(new Random().nextInt(MarketStorage.CONSUMER_THREAD_SLEEP));

                //消费对象
                CommodityObj commodityObj = MarketStorage.blockingQueue.take();
                System.out.println(this + " consumer obj ->" + commodityObj);
                MarketStorage.getConsumerObj_Count.getAndIncrement();//计数器++
                System.out.println("getConsumerObj_Count is :" + MarketStorage.getConsumerObj_Count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


市场演示仓库 - 调度生产者消费者

/**
 * 市场演示仓库
 *
 * @author wei.Li by 14-8-21.
 */
public class MarketStorage {

    //生产者线程池
    protected static final ExecutorService EXECUTOR_SERVICE_PRODUCER
            = Executors.newFixedThreadPool(10);
    //启动生产者线程数量
    protected static final int PRODUCER_THREAD_NUM = 2;
    //生产者线程睡眠随机最大时间
    protected static final int PRODUCER_THREAD_SLEEP = 200;
    //生产者生成对象次数
    protected static AtomicInteger getProducerObj_Count = new AtomicInteger(0);
    //是否生产
    protected static boolean isRun_Producer = true;


    //消费者线程池
    protected static final ExecutorService EXECUTOR_SERVICE_CONSUMER
            = Executors.newFixedThreadPool(10);
    //启动消费者线程数量
    protected static final int CONSUMER_THREAD_NUM = 20;
    //消费者线程睡眠随机最大时间
    protected static final int CONSUMER_THREAD_SLEEP = 1000;
    //消费者消费对象次数
    protected static AtomicInteger getConsumerObj_Count = new AtomicInteger(0);
    //是否消费
    protected static boolean isRun_Cousumer = true;

    //市场仓库-存储数据的队列 默认仓库容量大小100
    /**
     * @see com.java.queue.LinkedBlockingQueue_#linkedBlockingQueue2Void()
     */
    protected static LinkedBlockingQueue<CommodityObj> blockingQueue
            = new LinkedBlockingQueue<CommodityObj>(100);

    /**
     * 生成生产者线程
     */
    private static void runProducer() {
        for (int i = 0; i < PRODUCER_THREAD_NUM; i++) {
            EXECUTOR_SERVICE_PRODUCER.submit(new Producer());
        }
    }

    /**
     * 生成消费者线程生成
     */
    private static void runConsumer() {
        for (int i = 0; i < CONSUMER_THREAD_NUM; i++) {
            Thread thread = new Thread(new Consumer());
            EXECUTOR_SERVICE_CONSUMER.submit(thread);
        }
    }

    /**
     * 停止线程生产与消费
     * 关闭线程池
     */
    private static void shumdown() {
        if (!EXECUTOR_SERVICE_PRODUCER.isShutdown()) {
            isRun_Producer = false;
            EXECUTOR_SERVICE_PRODUCER.shutdown();
        }
        if (!EXECUTOR_SERVICE_CONSUMER.isShutdown()) {
            isRun_Cousumer = false;
            EXECUTOR_SERVICE_CONSUMER.shutdown();
        }
    }


    public static void main(String[] args) {
        runConsumer();
        runProducer();

        /**
         * 1 min 后停止执行
         */
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                shumdown();
                System.out.println("~~~~~~~~~~~~ shumdown done ~~~~~~~~~~~~~~");
            }
        }, 1000 * 60L);
    }
}


执行结果部分内容

...
...
...
com.java.queue.example.Producer@517f906c producer obj succeed->Obj{objId='1c80afd0-6d4d-4f6b-bd52-a1ed48d62136'}
producerObj_Count->109
com.java.queue.example.Consumer@352ebfc0 consumer obj ->Obj{objId='1c80afd0-6d4d-4f6b-bd52-a1ed48d62136'}
consumerObj_Count->109
com.java.queue.example.Consumer@2bcfaa37 consumer obj ->Obj{objId='fd6c17fb-cb78-4542-883d-0a87e12bb454'}
consumerObj_Count->110
com.java.queue.example.Producer@1ddc8d7a producer obj succeed->Obj{objId='fd6c17fb-cb78-4542-883d-0a87e12bb454'}
producerObj_Count->110
com.java.queue.example.Producer@517f906c producer obj succeed->Obj{objId='2e12de1e-648f-4edc-8620-9ad36313055e'}
producerObj_Count->111
com.java.queue.example.Consumer@271d296 consumer obj ->Obj{objId='2e12de1e-648f-4edc-8620-9ad36313055e'}
consumerObj_Count->111
~~~~~~~~~~~~ shumdown done ~~~~~~~~~~~~~~
com.java.queue.example.Producer@1ddc8d7a producer obj succeed->Obj{objId='5b91f0fa-a000-41cc-b74f-088fd6f04c01'}
producerObj_Count->112
com.java.queue.example.Consumer@3f32bcde consumer obj ->Obj{objId='5b91f0fa-a000-41cc-b74f-088fd6f04c01'}
consumerObj_Count->112
com.java.queue.example.Producer@517f906c producer obj succeed->Obj{objId='bebff1c2-8489-40bb-a742-04f56461b2d4'}
producerObj_Count->113
com.java.queue.example.Consumer@6ca1879 consumer obj ->Obj{objId='bebff1c2-8489-40bb-a742-04f56461b2d4'}
consumerObj_Count->113


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值