我在生产者-消费者场景中使用 ConcurrentLinkedQueue。我的生产者是我的应用程序中所有方法调用的单例:Producer.getInstance().add("foo"); 并且 add() 方法调用 ConcurrentLinkedQueue 提供方法。
public void add(String message) {
myQueue.offer(message);
}
否则,我让我的消费者在另一个线程中运行,并简单地在生产者内部的 ConcurrentLinkedQueue 上调用 poll 方法。
编辑:
在 if ((buffer = myQueue.poll()) != null) { } 之间添加代码
CRActiveMQProducer 是一个 Singleton,它初始化与我的 ActiveMQ 服务器的连接并使用 send() 方法发送消息。
private StringBuffer stringBuffer = new StringBuffer();
public void run() {
while(condition) {
String buffer = null;
if ((buffer = myQueue.poll()) != null) {
stringBuffer.append(buffer);
numberMessage++;
if (numberMessage >= 10000) {
CRActiveMQProducer.getInstance().send(stringBuffer.toString());
stringBuffer = stringBuffer.delete(0, stringBuffer.length());
numberMessage = 0L;
}
}
}
}
我调用了 Producer add() 方法 5000 万次(是的,它很大,但它只是应该完成的调用次数的 2.5%)
无论如何,我得到了 OutOfMemory 异常,我尝试使用 VisualVM 读取堆转储,我发现这个 OOM 是由大量 ConcurrentLinkedQueue$Node 实例(超过 3000 万个)引起的。我想我对每个 offer() 或 poll() 方法调用都有一个新节点,但不是 100% 确定(无法加载完整的堆转储......)。
您认为这是 ConcurrentLinkedQueue 的正常行为吗?或者只是我做错了什么?谢谢!