社区
Java SE
帖子详情
ConcurrentLinkedQueue的size()方法问题
whlxjq520
2008-12-27 02:01:28
再ConcurrentLinkedQueue的API中有这样一段描述:
需要小心的是,与大多数 collection 不同,size 方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前元素的数量需要遍历这些元素。
那位熟悉这个的朋友,旁忙解释一下.我的理解是他会随时间的不同size()也回变化,但好像每个collection都是这样的啊
是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗?
...全文
854
8
打赏
收藏
ConcurrentLinkedQueue的size()方法问题
再ConcurrentLinkedQueue的API中有这样一段描述: 需要小心的是,与大多数 collection 不同,size 方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前元素的数量需要遍历这些元素。 那位熟悉这个的朋友,旁忙解释一下.我的理解是他会随时间的不同size()也回变化,但好像每个collection都是这样的啊 是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗?
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
8 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
whlxjq520
2008-12-29
打赏
举报
回复
多谢指点,结贴去了!
老紫竹
2008-12-29
打赏
举报
回复
楼上说的不错哦!
jdk的每个类其设计目的是比较明确的,特别是1.5以后新加的一些类。
云上飞翔
2008-12-29
打赏
举报
回复
[Quote=引用 5 楼 whlxjq520 的回复:]
多谢前辈指点,有点笨哦,还是有点怀疑。
因为我的程序只是 if( conListObj.size() == a ){} 判断一下集合的大小并不用在后面用到,也同样不可以吗?我的程序刚好就用了synchronized,而没用用到isEmpty(),一定改正!
[/Quote]
答:关键的因素是:设计ConcurrentLinkedQueue时,力求最大的并发执行操作的优势.如果设计人员用传统的方法(即:定义一个private int size;变量,用于跟踪队列中元素个数,然后通过int size(){return size;}直接返回),这样是不需要遍历了O(1),但是:ConcurrentLinkedQueue本来就是用于多个并发线程的
尽最大努力的并发操作的优势的
,若这样设计(传统方案),显然这些线程在size上将成为操作的"瓶颈"了.失去了尽最大努力的并发操作优势了.
whlxjq520
2008-12-28
打赏
举报
回复
多谢前辈指点,有点笨哦,还是有点怀疑。
因为我的程序只是 if( conListObj.size() == a ){} 判断一下集合的大小并不用在后面用到,也同样不可以吗?我的程序刚好就用了synchronized,而没用用到isEmpty(),一定改正!
whlxjq520
2008-12-28
打赏
举报
回复
有点明白了,谢谢了!
云上飞翔
2008-12-27
打赏
举报
回复
[Quote=引用 2 楼 whlxjq520 的回复:]
我不是要知道它的内部实现
我的问题是:是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗?
请高手指点
[/Quote]
答:一般的List(如:LinkedList),要得到它的长度,直接它的调用size(),这个size()是O(1)级的.
而楼主的ConcurrentLinkedQueue,要得到它的长度,也是直接它的调用size(),但它的这个size()是O(n)级的[正如API手册中所说].为什么它是O(n)级?即:楼主说的:它一定要通过遍历啊?
是的.一定要通过遍历.因为这是一个并发的LIST.
其实楼主即使:
int elements=conListObj.size();//得到
这个时刻的
元素个素
System.out.println(elements);//其实在
执行该语句时
, elements中的值
已经不是准确的元素的size了
(因为是并发的原因,可能其它线程又已经加入了新的元素了)
因此:通常写程序,要获取准确的元素个素是不容易了.若强加synchronized,则又失去ConcurrentLinkedQueue最大的并发执行操作的优势了.
通常写程序(多线程协作)可用isEmpty()
以上仅供你参考
whlxjq520
2008-12-27
打赏
举报
回复
我不是要知道它的内部实现
我的问题是:是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗?
请高手指点
szws
2008-12-27
打赏
举报
回复
size()方法的内部实现,就是遍历一遍队列,再返回元素个数的
Con
current
Link
ed
Queue
使用
方法
它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先进先出的原则。头是最先加入的,尾是最近加入的。插入元素是追加到尾上。提取一个元素是从头提取。当多个线程共享访问一个公共 collection 时,Con
current
Link
ed
Queue
是一个恰当的选择。该队列不允许null元素。此实现采用了有效的“无等待 (wait-free)”算法,该算法基于 Mag
ed
M. Michael 和
那些年我们踩过的坑-Con
current
Link
ed
Queue
.
size
慢
Con
current
Link
ed
Queue
作为队列 有时候需要调用
size
方法
看下 队列中是否有数据 可当这个队列大小比较大的时候发现
size
方法
执行比较慢 可以看下一下源码 public int
size
() { int count = 0; for (Node<E> p = first(); p != null; p = succ(p)) if (...
Con
current
Link
ed
Queue
常用
方法
:
Con
current
Link
ed
Queue
常用
方法
: 增: add :底层调用offer offer : 将指定元素插入此队列的尾部 删: poll 是从队列取出元素并且删除该元素 remove 如果此元素不存在,则返回 false,移除成功返回true 读: peek() 获取但不移除此队列的头;如果此队列为空,则返回 null contains(Object o) 如果此队列...
Con
current
Link
ed
Queue
使用和
方法
介绍(转载)
https://www.cnblogs.com/yangzhenlong/p/8359875.html (原文地址) 定义 一个基于链接节点的无界线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。 新的元素插入到队列的尾部,队列获取操作从队列头部获得元素。当多个线程共享访问一个公共 collection 时,Con
current
Link
ed
Queue
是一个恰当的选择。此队列不允许使用 null 元素。 ...
Con
current
Link
ed
Queue
非阻塞无界链表队列
结果实际是一个减法操作。注意,调用Con
current
SkipListMap的
size
时,由于多个线程可以同时对映射表进行操作,所以映射表需要遍历整个链表才能返回元素个数,这个操作是个O(log(n))的操作。值得注意的是,在使用Con
current
Link
ed
Queue
时,如果涉及到队列是否为空的判断,切记不可使用
size
()==0的做法,因为在
size
()
方法
中,是通过遍历整个链表来实现的,在队列元素很多的时候,
size
()
方法
十分消耗性能和时间,只是单纯的判断队列为空使用isEmpty()即可!
Java SE
62,614
社区成员
307,327
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章