- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一段代码可以从队列中获取所有元素。之后我不关心队列的状态,我可以确信在我从队列中删除元素时队列不会被修改。
我最初使用迭代器来提取元素,因为我认为它比轮询元素更快...
但我运行了以下测试:
ConcurrentLinkedQueue<Object> queue = new ConcurrentLinkedQueue<>();
for (int i=0; i < 1000000; i++)
queue.add(new Object());
LinkedList<Object> list = new LinkedList<>();
long start = System.currentTimeMillis();
for (Object object: queue)
list.add(object);
long time1 = System.currentTimeMillis() - start;
list = new LinkedList<>();
start = System.currentTimeMillis();
Object object;
while ((object = queue.poll()) != null)
list.add(object);
long time2 = System.currentTimeMillis() - start;
System.out.println(time1 + " " + time2);
我得到了以下输出(平均超过 100 次运行)
1169 46
我的问题是:为什么轮询比迭代快?这对我来说完全不直观,因为 poll 必须修改队列,而 iterate 只需要查看状态。
编辑 --- 格雷是对的
我在循环中运行它并获得了输出(首先应该这样做)
1180 46
1422 25
287 32
14 26
226 26
236 25
12 26
14 25
13 25
13 26
13 25
268 25
13 25
14 176
13 26
13 26
13 25
13 25
13 26
13 24
13 26
13 25
...
最佳答案
My question is: Why is poll faster than iterate? It is completely unintuitive to me because poll will have to modify the queue and iterate will only have to look at the state.
正如@csoroiu 指出的那样,这似乎是热点编译器问题。考虑到 Java 的工作原理,在开始像这样进行计时调用之前“预热”您的应用程序非常重要。
如果我在一个方法中运行您的测试 100 次,我最初看到由于 GC 开销和其他 JVM 魔术而导致的性能大不相同。但是,在添加一些 .clear()
方法和方法末尾的 System.gc()
之后,性能数字与迭代器获胜更加一致:
108 143
89 152
83 148
78 140
79 153
90 155
...
有关更多详细信息,请在此处查看 Peter 的回答:CPU execution time in Java
有关如何像这样正确地进行微基准测试的大量更多信息,请参阅这个详尽的答案:How do I write a correct micro-benchmark in Java?
关于java - 为什么 Queue.poll 比 Iteration 快? (java.util.concurrent.ConcurrentLinkedQueue),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18923021/
我在迭代时更新ConcurrentLinkedQueue。理论上,该队列上的迭代器在到达队列末尾之前不应停止。但是,在我的程序中(如下所示),迭代器在迭代队列的初始状态(没有更新)后停止。我应该怎样解
假设我有 ConcurrentLinkedQueue 类型的类字段。此类的一些方法向该队列提供新元素。还有一些其他方法需要轮询此时队列中的所有元素。 我无法在循环中使用poll(),因为在循环尚未完成
作为我项目的一部分,我需要创建一个包含固定数量线程的线程池。每当线程分配给不同的进程时,我也需要与线程一起分配那么多 session 。我想使用 ConcurrentLinkedQueue (固定大小
我正在开发一个项目,其中我将某些数据包添加到队列中以便稍后处理(接下来的 600 毫秒滴答处理队列中的所有数据包)。 但是,我目前遇到了麻烦,因为当在同一周期中接收到两个数据包时,队列的行为非常奇怪。
我正在开发一个 Andoid 应用程序,它由在后台运行的服务和连接到该服务的一些 Activity 组成。该服务在它自己的进程上运行。 我的Service主要有3个类:ServiceMain、Serv
您能否澄清一下,我们是否需要使用显式同步或锁来使用 ConcurrentLinkedQueue?我特别想知道以下 ConcurrentLinkedQueue 方法是否需要同步调用。 添加 清除 尺寸
当前正在 for 循环中处理的元素是队列的头部吗? private Queue users = new ConcurrentLinkedQueue(); for(User u : users){
我想知道在什么情况下 ConcurrentLinkedQueue 无法从其集合中删除元素。该项目存在,它在集合内但调用 SomeConcurrentLinkedQueue.remove(item) 不
我想实现一个监视器队列,两个不相关的线程可以共享它的附加内容。在这种情况下,仅使用 ConcurrentLinkedQueue 就足够了,还是我应该采取不同的做法?我想实现 Activity 对象设计
我想使用 ConcurrentLinkedQueue在原子中lock-free方式: 多个并发线程将事件插入队列,其他线程将处理它们。队列未绑定(bind),我不希望任何线程等待或被锁定。然而,阅读部
阅读 Java's ConcurrentLinkedQueue Docs ,我想知道为什么实现无法存储大小: Beware that, unlike in most collections, the
我想使用 java.util.ConcurrentLinkedQueue 作为 Servlet 的非持久队列。这是该类(class)的 javadoc 中的简介。 An unbounded threa
如何在 Java 中使用 ConcurrentLinkedQueue? 使用这个LinkedQueue,我需要担心队列中的并发吗?还是我只需要定义两个方法(一个从列表中检索元素,另一个将元素添加到列表
当我们使用诸如 ConcurrentLinkedQueue 甚至一些 BlockingQueue 之类的内置队列之一时,单个调用是原子的并且保证是线程安全的。 但是当对 API 的 5 次调用中,有
我有一个工作线程,它应该迭代 ArrayList 。其他线程可以添加和删除对象(队列)。但ArrayList不是线程安全的。使用 ConcurrentLinkedQueue 可以吗?而不是ArrayL
我有以下代码: Queue localMsgQueue; //inside the constructor localMsgQueue = new ConcurrentLinkedQueue(); p
我广泛使用 ConcurrentLinkedQueue 进行多消耗任务排队,以前从未遇到过此问题。场景如下: 用一些任务填充我的队列 运行多个线程(在本例中为 2 个),这些线程将从队列中池化任务 当
我的线程永远运行并在 ConcurrentLinkedQueue#peek() 之后调用 ConcurrentLinkedQueue#poll()。 但在某些情况下,线程似乎挂起。我知道这有点含糊但是
我目前正在开发一个 Java 项目,该项目在原始数据包通过网络时对其进行处理。数据由libpcap读入,然后每个数据包放入一个byte[],然后放入一个ConcurrentLinkedQueue,线程
使用ConcurrentLinkedQueue时出现以下错误: Error : local variables referenced from a lambda expression must be
我是一名优秀的程序员,十分优秀!