ArrayBlockingQueue生产者消费者

官方描述

一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。

这是一个典型的“有界缓存区”,固定大小的数组在其中保持生产者插入的元素和使用者提取的元素。一旦创建了这样的缓存区,就不能再增加其容量。试图向已满队列中放入元素会导致操作受阻塞;试图从空队列中提取元素将导致类似阻塞。

此类支持对等待的生产者线程和使用者线程进行排序的可选公平策略。默认情况下,不保证是这种排序。然而,通过将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程。公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。

此类及其迭代器实现了 CollectionIterator 接口的所有可选 方法。

此类是 Java Collections Framework 的成员。

package com.thread.arrayblockingqueue;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Apple{
    private String name;
    public Apple(String name){
        this.name = name;
    }
    public String toString(){
        return this.name;
    }
}
class Basket{
    BlockingQueue<Apple> basket = new ArrayBlockingQueue<Apple>(3);
    public String add(Apple apple) throws InterruptedException{

        if(basket.size() >=3){
            return ",篮子已满。。等待取走";
        }else{
            basket.put(apple);
            return "成功生产" + apple.toString();
        }

    }
    public String sub() throws InterruptedException{
        if(basket.size()<=0){
            return (",已取完。。等待生产");
        }else{
            return ",成功取走" + basket.take().toString();
        }

    }
}
class Producer implements Runnable{
    private Random r = new Random();
    private String name;
    private Basket basket;
    public Producer(String name, Basket basket){
        this.name = name;
        this.basket = basket;
    }
    @Override
    public void run() {
        int i = 0;
        while(true){
            try {
                System.out.println("生产者:" + name +",尝试生产。。" + basket.add(new Apple("苹果"+i++)));
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                Thread.sleep(r.nextInt(5)*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

}
class Consumer implements Runnable{
    private Random r = new Random();
    private String name;
    private Basket basket;
    public Consumer(String name, Basket basket){
        this.name = name;
        this.basket = basket;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try {
                System.out.println("消费者:" +name+"尝试取走"+basket.sub());
                Thread.sleep(r.nextInt(10)*1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
public class Test01 {
    public static void main(String[] args) {
        Basket b = new Basket();
        Producer p1 = new Producer("p1", b);
        Consumer c1 = new Consumer("c1", b);
        Consumer c2 = new Consumer("c2", b);
        ExecutorService es = Executors.newCachedThreadPool();
        es.execute(p1);
        es.execute(c1);
        es.execute(c2);
    }
}

效果

消费者:c1尝试取走,已取完。。等待生产
消费者:c2尝试取走,已取完。。等待生产
生产者:p1,尝试生产。。成功生产苹果0
消费者:c2尝试取走,成功取走苹果0
生产者:p1,尝试生产。。成功生产苹果1
生产者:p1,尝试生产。。成功生产苹果2
消费者:c1尝试取走,成功取走苹果1
消费者:c2尝试取走,成功取走苹果2
生产者:p1,尝试生产。。成功生产苹果3
生产者:p1,尝试生产。。成功生产苹果4
消费者:c1尝试取走,成功取走苹果3
消费者:c1尝试取走,成功取走苹果4
消费者:c2尝试取走,已取完。。等待生产
消费者:c1尝试取走,已取完。。等待生产
生产者:p1,尝试生产。。成功生产苹果5
消费者:c1尝试取走,成功取走苹果5
消费者:c2尝试取走,已取完。。等待生产
生产者:p1,尝试生产。。成功生产苹果6
消费者:c2尝试取走,成功取走苹果6
生产者:p1,尝试生产。。成功生产苹果7
消费者:c2尝试取走,成功取走苹果7
消费者:c2尝试取走,已取完。。等待生产
生产者:p1,尝试生产。。成功生产苹果8
消费者:c2尝试取走,成功取走苹果8
生产者:p1,尝试生产。。成功生产苹果9
生产者:p1,尝试生产。。成功生产苹果10
消费者:c1尝试取走,成功取走苹果9
消费者:c2尝试取走,成功取走苹果10
时间: 2024-11-07 20:09:48

ArrayBlockingQueue生产者消费者的相关文章

阻塞队列和生产者-消费者模式

阻塞队列提供了可阻塞的put和take方法.如果队列满了put将阻塞到有空间可用,如果队列为空,take将阻塞到有元素可用.队列可以是有界和无界的,无界的队列put将不会阻塞. 阻塞队列支持生产者消费者模式,该模式将找出需要完成的工作,和执行工作分开.生产者-消费者模式能简化开发过程,因为消除了生产者和消费者之间的代码依赖性,此外,该模式还将生产数据的过程和使用数据的过程解耦开来. 在基于阻塞队列构建的生产者-消费者设计中个,当数据生成时,生产者把数据放入队列,当消费者处理数据时,将从队列中获取

使用BlockingQueue的生产者消费者模式

BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出:在生产者消费者模式中,通过队列的方式可以很方便的实现两者之间的数据共享.强大的BlockingQueue使我们不用关心什么时候需要阻塞线程,什么时候需要唤醒线程. BlockingQueue的

生产者消费者模式(转)

本文转载自博文系列架构设计:生产者/消费者模式.文中对原文格式进行了稍加整理. 概述 今天打算来介绍一下“生产者/消费者模式”,这玩意儿在很多开发领域都能派上用场.由于该模式很重要,打算分几个帖子来介绍.今天这个帖子先来扫盲一把.如果你对这个模式已经比较了解,请跳过本扫盲帖,直接看下一个帖子(关于该模式的具体应用) . 看到这里,可能有同学心中犯嘀咕了:在四人帮(GOF)的23种模式里面似乎没听说过这种嘛!其实GOF那经典的23种模式主要是基于OO的(从书名<Design Patterns: E

线程同步之生产者消费者

前言: 前面因时间关系,未将“生产者消费者问题”实例的介绍发布在博客随笔中,故本文作为对之前“多线程”一文的补充.概念: 生产者消费者问题(Bounded-buffer problem),是一个多线程同步问题的经典案例.这个案例中主要实现的是两个角色协同对同一资源进行访问.生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗这些数据.该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据. 设计:本博客前面关于多线程的文

Java 并发编程(四)阻塞队列和生产者-消费者模式

阻塞队列 阻塞队列提供了可阻塞的 put 和 take 方法,以及支持定时的 offer 和 poll 方法.如果队列已经满了,那么put方法将阻塞直到有空间可以用:如果队列为空,那么take方法将一直阻塞直到有元素可用.队列可以使有界的,也可以是无界的,无界队列永远都不会充满,因此无界队列上的put方法永远不会阻塞.一种常见的阻塞生产者-消费者模式就是线程池与工作队列的组合,在 Executor 任务执行框架中就体现了这种模式. 意义:该模式能简化开发过程,因为他消除了生产者和消费者类之间的代

模拟生产者消费者(多条生产线多个消费者)

1 import java.util.concurrent.ArrayBlockingQueue; 2 import java.util.concurrent.BlockingQueue; 3 import java.util.concurrent.locks.Lock; 4 import java.util.concurrent.locks.ReentrantLock; 5 /** 6 * 模拟生产者消费者(多条生产线多个消费者) 7 * 仓库容量为10 8 * 保证仓库充足量为5 9 * @

多线程的并发执行应用(生产者消费者模式)

在实际的开发中我们为了提高CPU的利用率,也提高程序的执行效率,我们经常使用多线程进行对数据进行并发处理,下面我举一个多线程并发执行的实例,大致意思就是 一个简单的生产者消费者模式,二个线程进行存数据,一个线程进行取数据. import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class BlockingQueueTest { /** * @param a

从生产者消费者窥探线程同步(上)

欢迎转载,转载请注明出处.尊重他人的一丢丢努力,谢谢啦! 阅读本篇之后,如果你觉得说得还有点道理,那不妨先戳一下从生产者消费者窥探线程同步(下) ,两篇一起嚼才更好呢. 最近复习了下生产者消费者模式,虽然对它不太陌生,但要说认认真真地实现,还真从来没有过,这里将它总结一下,有不妥或者见识不到之处,欢迎留言指出. 为什么要使用 大概基于以下2点: (1)可以实现解耦 大多数设计模式,都会创造出一个第三者来担任解耦角色.比如末班模式的模板类,工厂模式的工厂类等.而消费者观察者模式则是使用拥塞队列来给

java 多线程并发系列之 生产者消费者模式的两种实现

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这种生产消费能力不均衡的问题,所以便有了生产者和消费者模式. 什么是生