队列LinkedBlockingQueue学习

来源:互联网 发布:本周重要财经数据 编辑:程序博客网 时间:2024/05/29 18:04

1.首先,Queue接口与List、set同级别,Queue不熟悉但是List和Set都很熟悉了,Queue也继承了Collection接口,LinkedList实现了Queue接口;

2. java.util.Queue接口是在java5中加入的,在java多线程应用中,使用率很高,多数生产消费模型的首选数据结构就是队列,java提供的线程安全的Queue可以分为阻塞队列(典型:BlockingQueue)和非阻塞队列(典型:ConcurrentLinkedQueue),在实际应用中要根据实际需要选用阻塞队列或非阻塞队列;

3.LInkedBlockingQueue是一个基于已链接节点的,范围任意的BlockingQueue的实现是基于链表的队列;按先进先出的顺序;新元素插入到队列的尾部,队列检索操作和获得位于队列头部的元素,链接队列的吞吐量常常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低;使用中要防止队列过度扩展,如果未指定容量,则等于Integer.MAX_VALUE.除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点;

使用阻塞队列的好处,多线程操作共同的队列时不需要额外的同步,另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减少两边的处理数度差距;

4.队列的2个基本操作:在队列尾部加入一个元素,和从队列头部移除一个元素;

5.方法:add 增加一个元素   如果队列已满,则抛出异常;

      remove移除并返回队列头部的元素    如果队列已空    则抛出NoSuchElementException异常;

      element返回队列头部的元素   如果队列为空    则抛出NoSuchElementException异常;

         offer添加一个元素并返回true  如果队列已满    则返回false;

      poll移除并返回队列头部的元素  如果队列为空   则返回null;

      peek返回队列头部的元素  如果队列为空   则返回null;

      put添加一个元素  如果队列满        则阻塞;

      take移除并返回队列头部的元素  如果队列为空   则阻塞;

      clear从队列彻底移除所有元素

6.注意事项:

1)如果未指定容量,默认容量为Integer.MAX_VALUE,容量范围可以在构造方法参数中指定作为防止队列过度扩展;

2)不接受null;如:在element时队列为空抛出异常说明是null时是不正确的;

3)实现了BlockingQueue接口;

4)实现了Collection和Iterator接口的所有可选方法;

5)项目中使用:

LinkedBlockingQueue<A> queue = (LinkedBlockingQueue<A>)getCurrentSessionAttribute(request,"viewedPackageQueue");

if(queue == null){

queue  = new LinkedBlockingQueue<A>();

}

if(queue.size() == 5 && !isContain(A,queue)){

queue.poll();

}

if(!isContain(A,queue)){

queue.offer(A);

}

setCurrentSessionAttribute(request,"viewedPackageQueue",queue);


/**
* 封装获取Session属性

* @param request
* @param name
* @return
*/
protected Object getCurrentSessionAttribute(HttpServletRequest request,String name){
return WebUtils.getSessionAttribute(request, name);
}

/**
* 封装设置Session属性

* @param request
* @param name
* @return
*/
protected void setCurrentSessionAttribute(HttpServletRequest request,String name, Object value){
WebUtils.setSessionAttribute(request, name, value);
}

7.ConcurrentLinkedQueue<E>:java.util.concurrent

一个基于链接节点的、无界的、线程安全的队列。FIFO;

当多线程共享一个公共collection时,ConcurrentLinkedQueue是一个恰当的选择,此队列不允许null元素;

扩展:

并发编程中的一种编程方式是把任务拆分为一些小的任务,即Runnable,然后再提交给一个Excutor执行,Excutor.executor在执行时使用内部的线程池完成操作。Executor在执行时使用内部线程池完成操作;

创建线程池:

Executor executor = Executors.newFixedThreadPool(10);   // 创建固定数目线程的线程持;

Executor executor = Executors.newCachedThreadPool(); // 创建一个可缓存的线程池,调用executor将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新的线程并添加到池中;

ExecutorService与生命周期

ExecutorService扩展了Executor并添加了一些生命周期管理的方法。一个Executor的生命周期有三种状态:运行、关闭、终止、Executor创建时处于运行状态、当调用ExecutorServie.shutdown()后,处于关闭状态,isShutdown方法返回true.这时,不应该再想Executor中添加任务,所有已添加的任务执行完毕后,Executor处于终止状态。





学习中参考了http://www.cnblogs.com/end/archive/2012/10/25/2738493.html

http://blog.csdn.net/ac903919/article/details/6967728

0 0