ConcurrentLinkedQueue使用和方法介绍详解编程语言
2023-06-13 09:11:46 时间
一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。offer和poll
新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许使用 null 元素。
offer(E e)
将指定元素插入此队列的尾部。
poll()
获取并移除此队列的头,如果此队列为空,则返回 null。
public static void main(String[] args) { ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); queue.offer("哈哈哈"); System.out.println("offer后,队列是否空?" + queue.isEmpty()); System.out.println("从队列中poll:" + queue.poll()); System.out.println("pool后,队列是否空?" + queue.isEmpty()); }
offer是往队列添加元素,poll是从队列取出元素并且删除该元素
执行结果
offer后,队列是否空?false 从队列中poll:哈哈哈 pool后,队列是否空?true
ConcurrentLinkedQueue中的add() 和 offer() 完全一样,都是往队列尾部添加元素
还有个取元素方法peekpeek()
获取但不移除此队列的头;如果此队列为空,则返回 null
public static void main(String[] args) { ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); queue.offer("哈哈哈"); System.out.println("offer后,队列是否空?" + queue.isEmpty()); System.out.println("从队列中peek:" + queue.peek()); System.out.println("从队列中peek:" + queue.peek()); System.out.println("从队列中peek:" + queue.peek()); System.out.println("pool后,队列是否空?" + queue.isEmpty()); }
执行结果:
offer后,队列是否空?false 从队列中peek:哈哈哈 从队列中peek:哈哈哈 从队列中peek:哈哈哈 pool后,队列是否空?falseremove
remove(Object o)
从队列中移除指定元素的单个实例(如果存在)
public static void main(String[] args) { ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); queue.offer("哈哈哈"); System.out.println("offer后,队列是否空?" + queue.isEmpty()); System.out.println("从队列中remove已存在元素 :" + queue.remove("哈哈哈")); System.out.println("从队列中remove不存在元素:" + queue.remove("123")); System.out.println("remove后,队列是否空?" + queue.isEmpty()); }
remove一个已存在元素,会返回true,remove不存在元素,返回false
执行结果:
offer后,队列是否空?false 从队列中remove已存在元素 :true 从队列中remove不存在元素:false remove后,队列是否空?truesize or isEmpty
size()
返回此队列中的元素数量
注意:
如果此队列包含的元素数大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。 需要小心的是,与大多数 collection 不同,此方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前的元素数需要进行一次花费 O(n) 时间的遍历。
所以在需要判断队列是否为空时,尽量不要用 queue.size() 0,而是用 !queue.isEmpty()
比较size()和isEmpty() 效率的示例:
场景:10000个人去饭店吃饭,10张桌子供饭,分别比较size() 和 isEmpty() 的耗时
public class Test01ConcurrentLinkedQueue { public static void main(String[] args) throws InterruptedException { int peopleNum = 10000;//吃饭人数 int tableNum = 10;//饭桌数量 ConcurrentLinkedQueue String queue = new ConcurrentLinkedQueue (); CountDownLatch count = new CountDownLatch(tableNum);//计数器 //将吃饭人数放入队列(吃饭的人进行排队) for(int i=1;i =peopleNum;i++){ queue.offer("消费者_" + i); //执行10个线程从队列取出元素(10个桌子开始供饭) System.out.println("-----------------------------------开饭了-----------------------------------"); long start = System.currentTimeMillis(); ExecutorService executorService = Executors.newFixedThreadPool(tableNum); for(int i=0;i tableNum;i++) { executorService.submit(new Dinner("00" + (i+1), queue, count)); //计数器等待,知道队列为空(所有人吃完) count.await(); long time = System.currentTimeMillis() - start; System.out.println("-----------------------------------所有人已经吃完-----------------------------------"); System.out.println("共耗时:" + time); //停止线程池 executorService.shutdown(); private static class Dinner implements Runnable{ private String name; private ConcurrentLinkedQueue String queue; private CountDownLatch count; public Dinner(String name, ConcurrentLinkedQueue String queue, CountDownLatch count) { this.name = name; this.queue = queue; this.count = count; @Override public void run() { //while (queue.size() 0){ while (!queue.isEmpty()){ //从队列取出一个元素 排队的人少一个 System.out.println("【" +queue.poll() + "】----已吃完..., 饭桌编号:" + name); count.countDown();//计数器-1 }
执行结果:
使用size耗时:757ms
使用isEmpty耗时:210
当数据量越大,这种耗时差距越明显。所以这种判断用isEmpty 更加合理
contains
contains(Object o)
如果此队列包含指定元素,则返回 true
public static void main(String[] args) throws InterruptedException { ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); queue.offer("123"); System.out.println(queue.contains("123")); System.out.println(queue.contains("234")); }
执行结果:
toArray
toArray()
返回以恰当顺序包含此队列所有元素的数组
toArray(T[] a)
返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型
public static void main(String[] args) throws InterruptedException { ConcurrentLinkedQueue String queue = new ConcurrentLinkedQueue String (); queue.offer("123"); queue.offer("234"); Object[] objects = queue.toArray(); System.out.println(objects[0] + ", " + objects[1]); //将数据存储到指定数组 String[] strs = new String[2]; queue.toArray(strs); System.out.println(strs[0] + ", " + strs[1]); }
执行结果:
iteratoriterator()
返回在此队列元素上以恰当顺序进行迭代的迭代器
public static void main(String[] args) throws InterruptedException { ConcurrentLinkedQueue String queue = new ConcurrentLinkedQueue String (); queue.offer("123"); queue.offer("234"); Iterator String iterator = queue.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }
ConcurrentLinkedQueue文档说明:
boolean isEmpty()
如果此队列不包含任何元素,则返回 true。
toArray(T[] a)
返回以恰当顺序包含此队列所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/16950.html
cjava相关文章
- SAP UI5 BaseObject.extend 方法的单步调试
- Java设计模式之简单工厂、工厂方法和抽象工厂详解编程语言
- python发送各类邮件的主要方法详解编程语言
- jquery.cookie使用方法详解编程语言
- java基础学习总结——equals方法详解编程语言
- ashx文件获取$.ajax()方法发送的数据详解编程语言
- 关于引入多个jquery冲突的问题(附一个很好用的validate前端验证框架及使用方法)详解编程语言
- Java中String类的方法及说明详解编程语言
- Java学习笔记之六java三种循环(for,while,do……while)的使用方法及区别详解编程语言
- python_day24_面向对象进阶1_内置方法详解编程语言
- JAVA中重写equals()方法的同时要重写hashcode()方法详解编程语言
- $.ajax()方法详解编程语言
- 10 种保护 Spring Boot 应用的绝佳方法详解编程语言
- Java:判断字符串是否为数字的五种方法详解编程语言
- JS产生四位随机数的方法详解编程语言
- javascript提高首屏加载速度的方法详解编程语言
- PHP实现不用事务mysql的另类方法详解编程语言
- PHP防止被重复请求接口的方法(网页端签名验证的方法)详解编程语言
- PHP替代session的方法详解编程语言
- php合并数组并保留键值的方法详解编程语言
- php 5.5使用 array_column的方法详解编程语言
- php charles 使用方法详解编程语言
- ABAP开发SELECTION-SCREEN: FUNCTION KEY 1,2,3,4,5的使用方法详解编程语言
- TABLE CONTROL使用方法详解编程语言
- abap 中 FIELD-SYMBOLS的使用方法详解编程语言
- SAP_ABAP_查找消息号在程序中使用位置的六种方法详解编程语言
- 解决Oracle ORA00058问题的方法(oracle00058)