再ConcurrentLinkedQueue的API中有这样一段描述:
需要小心的是,与大多数 collection 不同,size 方法不是 一个固定时间操作。由于这些队列的异步特性,确定当前元素的数量需要遍历这些元素。 
那位熟悉这个的朋友,旁忙解释一下.我的理解是他会随时间的不同size()也回变化,但好像每个collection都是这样的啊
是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗?

解决方案 »

  1.   

    size()方法的内部实现,就是遍历一遍队列,再返回元素个数的
      

  2.   

    我不是要知道它的内部实现 
    我的问题是:是不是要得到它的长度,就一定只有通过遍历啊.直接用size()一定不可以吗? 
    请高手指点
      

  3.   


    答:一般的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()以上仅供你参考
      

  4.   

    多谢前辈指点,有点笨哦,还是有点怀疑。
     因为我的程序只是 if( conListObj.size() == a ){} 判断一下集合的大小并不用在后面用到,也同样不可以吗?我的程序刚好就用了synchronized,而没用用到isEmpty(),一定改正!
      

  5.   

    答:关键的因素是:设计ConcurrentLinkedQueue时,力求最大的并发执行操作的优势.如果设计人员用传统的方法(即:定义一个private int size;变量,用于跟踪队列中元素个数,然后通过int size(){return size;}直接返回),这样是不需要遍历了O(1),但是:ConcurrentLinkedQueue本来就是用于多个并发线程的尽最大努力的并发操作的优势的,若这样设计(传统方案),显然这些线程在size上将成为操作的"瓶颈"了.失去了尽最大努力的并发操作优势了.
      

  6.   

    楼上说的不错哦!jdk的每个类其设计目的是比较明确的,特别是1.5以后新加的一些类。