深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 -凯发k8网页登录

关注后端架构、中间件、分布式和并发编程

   :: 凯发k8网页登录首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  111 随笔 :: 10 文章 :: 2680 评论 :: 0 trackbacks

queue是jdk 5以后引入的新的集合类,它属于java collections framework的成员,在collection集合中和list/set是同一级别的接口。通常来讲queue描述的是一种fifo的队列,当然不全都是,比如priorityqueue是按照优先级的顺序(或者说是自然顺序,借助于comparator接口)。

下图描述了java collections framework中queue的整个家族体系。

对于queue而言是在collection的基础上增加了offer/remove/poll/element/peek方法,另外重新定义了add方法。对于这六个方法,有不同的定义。

抛出异常

返回特殊值

操作描述

插入

add(e)

offer(e)

将元素加入到队列尾部

移除

remove()

poll()

移除队列头部的元素

检查

element()

peek()

返回队列头部的元素而不移除此元素

特别说明的是对于queue而言,规范并没有规定是线程安全的,为了解决这个问题,引入了可阻塞的队列blockingqueue。对于blockingqueue而言所有操作的是线程安全的,并且队列的操作可以被阻塞,直到满足某种条件。queue的另一个子接口deque描述的是一个双向的队列。与queue不同的是,deque允许在队列的头部增加元素和在队列的尾部删除元素。也就是说deque是一个双向队列。二者功能都有的队列就是blockingdeque,这种阻塞队列允许在队列的头和尾部分别操作元素,应该说是queue中功能最强大的实现。

 

在jdk 5之前linkedlist就已经存在,而且本身实现都是一种双向队列。所以到了jdk 5以后就将linkedlist同时实现deque接口,这样linkedlist就又属于queue的一部分了。

通常情况下queue都是靠链表结构实现的,但是链表意味着有一些而外的引用开销,如果是双向链表开销就更大了。所以为了节省内存,一种方式就是使用固定大小的数组来实现队列。在这种情况下队列的大小是固定,元素的遍历通过数组的索引进行,很显然这是一种双向链表的模型。arraydeque就是这样一种实现。

另外arrayblockingqueue也是一种数组实现的队列,但是却没有改造成双向,仅仅实现了blockingqueue的模型。理论上和arraydeque一样也应该容易改造成双向的实现。

priorityqueue和priorityblockingqueue实现了一种排序的队列模型。这很类似与sortedset,通过队列的comparator接口或者comparable元素来排序元素。这种情况下元素在队列中的出入就不是按照fifo的形式,而是根据比较后的自然顺序来进行。

cocurrentlinkedqueue是一种线程安全却非阻塞的fifo队列,这种队列通常实现起来比较简单,但是却很有效。在接下来的章节会详细的描述它。

synchronousqueue是一种特别的blockingqueue,它只是把一个add/offer操作的元素直接移交给remove/take操作。也就是说它本身不会缓存任何元素,所以严格意义上说来讲并不是一种真正的队列。此队列维护一个线程列表,这些线程等待从队列中加入元素或者移除元素。简单的说,至少有一个remove/take操作时add/offer操作才能成功,同样至少有一个add/offer操作时remove/take操作才能成功。这是一种双向等待的队列模型,出队列等待加入等列,而入队列又等待出队列。这种队列的好处在于能够最大线程的保持吞吐量却又是线程安全的。所以对于一个需要快速处理的任务队列,synchronousqueue是一个不错的选择。

 

blockingqueue还有一种实现delayqueue,这种实现允许每一个元素(delayed)带有一个延时时间,当调用take/poll的时候会检测队列头元素这个时间是否<=0,如果满足就是说已经超时了,那么此元素就可以被移除了,否则就会等待。特别说明的是这个头元素应该是最先被超时的元素(这个时间是绝对时间)。这个类设计很巧妙,被用于scheduledfuturetask来进行定时操作。希望后面会开辟一个章节讲讲这里面的想法。实在不行在讲线程池部分肯定会提到这个。

 

 



©2009-2014 imxylz
|求贤若渴
posted on 2010-07-21 12:21 imxylz 阅读(21305) 评论(5)     所属分类: java concurrency
# re: 深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 2010-07-21 12:46
e vais résumer mes recherches et ce que j'ai fait:
pour commencer j'ai windows xp et mon but et de pouvoir créer un custom widget, le prendre dans le designer, le déposer sur une qdialog et que le tout se lance.
je pars sur un custom widget simple et un qdialog simple c'est a dire je crée des nouveaux projets dans qtcreator sans modifier les fichiers générés. (un qt custom designer widget et un qt gui application avec une class base qdialog)  回复  
  

# re: 深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 2010-07-21 12:47
e vais résumer mes recherches et ce que j'ai fait:
pour commencer j'ai windows xp et mon but et de pouvoir créer un custom widget, le prendre dans le designer, le déposer sur une qdialog et que le tout se lance.

  回复  
  

# re: 深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 2010-07-21 12:48
a ce moment là je dois dire que je pense que c'est gagné, je place mon widget dans ma fenêtre, je lance la compilation erreur trouve pas les .h du widget, j'ajoute dans le pro includepath = chemin des headers du custom je relance et la j'ai   回复  
  

# re: 深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 2010-07-21 12:49
aut il ajouter d'autres options dans les pro du widget ou du qdialog ?
existe t'il un tutorial qui explique comment faire ça avec qtcreator 2 ?
  回复  
  

# re: 深入浅出 java concurrency (19): 并发容器 part 4 并发队列与queue简介 2011-07-27 12:16
jdk1.6下 concurrentlinkedqueue 的add 和 offer一样了;add直接调用了offer方法。

  回复  
  


©2009-2014
网站地图