https://www.cnblogs.com/yangzhenlong/p/8359875.html    (原文地址)

定义

一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。
新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使用 null 元素。

offer和poll

offer(E e) 
          将指定元素插入此队列的尾部。

poll() 
          获取并移除此队列的头,如果此队列为空,则返回 null。

 
  1. public static void main(String[] args) {

  2. ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

  3. queue.offer("哈哈哈");

  4. System.out.println("offer后,队列是否空?" + queue.isEmpty());

  5. System.out.println("从队列中poll:" + queue.poll());

  6. System.out.println("pool后,队列是否空?" + queue.isEmpty());

  7. }

offer是往队列添加元素,poll是从队列取出元素并且删除该元素

执行结果

offer后,队列是否空?false
从队列中poll:哈哈哈
pool后,队列是否空?true

ConcurrentLinkedQueue中的add() 和 offer() 完全一样,都是往队列尾部添加元素

还有个取元素方法peek

peek() 
          获取但不移除此队列的头;如果此队列为空,则返回 null

 
  1. public static void main(String[] args) {

  2. ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

  3. queue.offer("哈哈哈");

  4. System.out.println("offer后,队列是否空?" + queue.isEmpty());

  5. System.out.println("从队列中peek:" + queue.peek());

  6. System.out.println("从队列中peek:" + queue.peek());

  7. System.out.println("从队列中peek:" + queue.peek());

  8. System.out.println("pool后,队列是否空?" + queue.isEmpty());

  9. }

执行结果:

offer后,队列是否空?false
从队列中peek:哈哈哈
从队列中peek:哈哈哈
从队列中peek:哈哈哈
pool后,队列是否空?false

remove

remove(Object o) 
          从队列中移除指定元素的单个实例(如果存在)

 
  1. public static void main(String[] args) {

  2. ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

  3. queue.offer("哈哈哈");

  4. System.out.println("offer后,队列是否空?" + queue.isEmpty());

  5. System.out.println("从队列中remove已存在元素 :" + queue.remove("哈哈哈"));

  6. System.out.println("从队列中remove不存在元素:" + queue.remove("123"));

  7. System.out.println("remove后,队列是否空?" + queue.isEmpty());

  8. }

remove一个已存在元素,会返回true,remove不存在元素,返回false

执行结果:

offer后,队列是否空?false
从队列中remove已存在元素 :true
从队列中remove不存在元素:false
remove后,队列是否空?true

size or isEmpty

size() 
          返回此队列中的元素数量

注意:

如果此队列包含的元素数大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
需要小心的是,与大多数 collection 不同,此方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前的元素数需要进行一次花费 O(n) 时间的遍历。
所以在需要判断队列是否为空时,尽量不要用 queue.size()>0,而是用 !queue.isEmpty()

比较size()和isEmpty() 效率的示例:

场景:10000个人去饭店吃饭,10张桌子供饭,分别比较size() 和 isEmpty() 的耗时

 
  1. public class Test01ConcurrentLinkedQueue {

  2. public static void main(String[] args) throws InterruptedException {

  3. int peopleNum = 10000;//吃饭人数

  4. int tableNum = 10;//饭桌数量

  5. ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

  6. CountDownLatch count = new CountDownLatch(tableNum);//计数器

  7. //将吃饭人数放入队列(吃饭的人进行排队)

  8. for(int i=1;i<=peopleNum;i++){

  9. queue.offer("消费者_" + i);

  10. }

  11. //执行10个线程从队列取出元素(10个桌子开始供饭)

  12. System.out.println("-----------------------------------开饭了-----------------------------------");

  13. long start = System.currentTimeMillis();

  14. ExecutorService executorService = Executors.newFixedThreadPool(tableNum);

  15. for(int i=0;i<tableNum;i++) {

  16. executorService.submit(new Dinner("00" + (i+1), queue, count));

  17. }

  18. //计数器等待,知道队列为空(所有人吃完)

  19. count.await();

  20. long time = System.currentTimeMillis() - start;

  21. System.out.println("-----------------------------------所有人已经吃完-----------------------------------");

  22. System.out.println("共耗时:" + time);

  23. //停止线程池

  24. executorService.shutdown();

  25. }

  26. private static class Dinner implements Runnable{

  27. private String name;

  28. private ConcurrentLinkedQueue<String> queue;

  29. private CountDownLatch count;

  30. public Dinner(String name, ConcurrentLinkedQueue<String> queue, CountDownLatch count) {

  31. this.name = name;

  32. this.queue = queue;

  33. this.count = count;

  34. }

  35. @Override

  36. public void run() {

  37. //while (queue.size() > 0){

  38. while (!queue.isEmpty()){

  39. //从队列取出一个元素 排队的人少一个

  40. System.out.println("【" +queue.poll() + "】----已吃完..., 饭桌编号:" + name);

  41. }

  42. count.countDown();//计数器-1

  43. }

  44. }

  45. }

执行结果:

使用size耗时:757ms

使用isEmpty耗时:210

当数据量越大,这种耗时差距越明显。所以这种判断用isEmpty 更加合理

contains

contains(Object o) 
          如果此队列包含指定元素,则返回 true

 
  1. public static void main(String[] args) throws InterruptedException {

  2. ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue();

  3. queue.offer("123");

  4. System.out.println(queue.contains("123"));

  5. System.out.println(queue.contains("234"));

  6. }

执行结果:

toArray

toArray() 
          返回以恰当顺序包含此队列所有元素的数组

toArray(T[] a) 
          返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型

 
  1. public static void main(String[] args) throws InterruptedException {

  2. ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();

  3. queue.offer("123");

  4. queue.offer("234");

  5. Object[] objects = queue.toArray();

  6. System.out.println(objects[0] + ", " + objects[1]);

  7. //将数据存储到指定数组

  8. String[] strs = new String[2];

  9. queue.toArray(strs);

  10. System.out.println(strs[0] + ", " + strs[1]);

  11. }

执行结果:

iterator

iterator() 
          返回在此队列元素上以恰当顺序进行迭代的迭代器

 
  1. public static void main(String[] args) throws InterruptedException {

  2. ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();

  3. queue.offer("123");

  4. queue.offer("234");

  5. Iterator<String> iterator = queue.iterator();

  6. while (iterator.hasNext()){

  7. System.out.println(iterator.next());

  8. }

  9. }

ConcurrentLinkedQueue文档说明:

构造方法摘要
ConcurrentLinkedQueue() 
          创建一个最初为空的 ConcurrentLinkedQueue。
ConcurrentLinkedQueue(Collection<? extends E> c) 
          创建一个最初包含给定 collection 元素的 ConcurrentLinkedQueue,按照此 collection 迭代器的遍历顺序来添加元素。

 

方法摘要
 booleanadd(E e) 
          将指定元素插入此队列的尾部。
 booleancontains(Object o) 
          如果此队列包含指定元素,则返回 true。
 booleanisEmpty() 
          如果此队列不包含任何元素,则返回 true。
 Iterator<E>iterator() 
          返回在此队列元素上以恰当顺序进行迭代的迭代器。
 booleanoffer(E e) 
          将指定元素插入此队列的尾部。
 Epeek() 
          获取但不移除此队列的头;如果此队列为空,则返回 null。
 Epoll() 
          获取并移除此队列的头,如果此队列为空,则返回 null。
 booleanremove(Object o) 
          从队列中移除指定元素的单个实例(如果存在)。
 intsize() 
          返回此队列中的元素数量。
 Object[]toArray() 
          返回以恰当顺序包含此队列所有元素的数组。
<T> T[]
toArray(T[] a) 
          返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐