并发编程-concurrent指南-阻塞队列-数组阻塞队列ArrayBlockingQueue

ArrayBlockingQueue类是实现了BlockingQueue.

ArrayBlockingQueue是一个有界的阻塞队列,其内部实现是将对象放在一个数组中。

放入元素方法:

(1) add(object)

  队列没满的话,放入成功。否则抛出异常(java.lang.IllegalStateException: Queue full)。

(2)offer(object):    

  将object加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.

(3)offer(E o, long timeout, TimeUnit unit)      

  可以设定等待的时间,如果在指定的时间内,还不能往队列中加入BlockingQueue,则返回失败。

(4)put(object)        

  把object加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程阻塞。直到BlockingQueue里面有空间再继续.

获取元素方法:

(1)poll(time)    

  取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null;

(2)poll(long timeout, TimeUnit unit)

  从BlockingQueue取出一个队首的对象,如果在指定时间内,队列一旦有数据可取,则立即返回队列中的数据。否则知道时间超时还没有数据可取,返回失败。

(3)take()

  取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入;

(4)drainTo()

  一次性从BlockingQueue获取所有可用的数据对象(还可以指定获取数据的个数),通过该方法,可以提升获取数据效率;不需要多次分批加锁或释放锁。

 

 构造方法:

如果为true,则按照 FIFO 顺序访问插入或移除时受阻塞线程的队列;如果为 false,则访问顺序是不确定的。

 

特点

ArrayBlocingQueue内部以FIFO(先进先出)的顺序对元素进行存储。

一个由数组支持的有界阻塞队列。

容纳大小是固定的。

队列中的头元素在所有元素之中是放入时间最久的那个,而尾元素则是最短的那个。

新元素插入到队列的尾部,队列检索操作是从队列头部开始获取元素。

一旦创建了这样的缓存区,就不能再增加容量。

默认情况下,不保证访问顺序。然而,通过在构造函数将公平性 (fairness) 设置为 true 而构造的队列允许按照 FIFO 顺序访问线程

公平性通常会降低吞吐量,但也减少了可变性和避免了“不平衡性”。

在JDK5/6中,LinkedBlockingQueue和ArrayBlocingQueue等对象的poll(long timeout, TimeUnit unit)存在内存泄露。

 

 

import java.util.concurrent.ArrayBlockingQueue;

/**
 * 生产者
 */
public class Producer extends Thread{
    private ArrayBlockingQueue<Object> queue;
    public Producer(ArrayBlockingQueue queue){
        this.queue = queue;
    }
    @Override
    public void run() {
        while(true){
            Object obj = new Object();
            try {
                queue.put(obj);
                System.out.println("producer:"+obj);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.util.concurrent.ArrayBlockingQueue;

/**
 * 消费者
 */
public class Consumer extends Thread{
    private ArrayBlockingQueue<Object> queue;
    public Consumer(ArrayBlockingQueue queue){
        this.queue = queue;
    }
    @Override
    public void run() {
        while(true){
            try {
                Object obj = queue.take();
                System.out.println("consumer:"+obj);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.util.concurrent.ArrayBlockingQueue;

public class Main {
    public static void main(String[] args) {
        //声明队列
        ArrayBlockingQueue queue = new ArrayBlockingQueue(10);

        //生产者
        Producer producer= new Producer(queue);
        producer.start();

        //消费者
        Consumer consumer= new Consumer(queue);
        consumer.start();
    }
}

 源码地址:https://github.com/qjm201000/concurrent_arrayBlockingQueue.git

posted @ 2018-12-18 15:20  qjm201000  阅读(315)  评论(0编辑  收藏  举报