Producer-Consumer シナリオで ConcurrentLinkedQueue を使用しています。私のプロデューサーは、私のアプリケーションのすべてのメソッドによって呼び出されるシングルトンです: Producer.getInstance().add("foo"); add() メソッドは ConcurrentLinkedQueue offer メソッドを呼び出します。
public void add(String message) {
myQueue.offer(message);
}
それ以外の場合は、Consumer を別のスレッドで実行し、Producer 内の ConcurrentLinkedQueue で poll メソッドを呼び出すだけです。
編集:
if ((buffer = myQueue.poll()) != null) { } の間にコードを追加します
CRActiveMQProducer は、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 インスタンス (30Millions 以上) によって引き起こされたことがわかりました。offer() または poll() メソッド呼び出しごとに新しいノードがあると思いますが、100% 確実ではありません (完全なヒープ ダンプを読み込めません...)。
これは ConcurrentLinkedQueue の通常の動作だと思いますか? それとも私が何か間違ったことをしているのですか?ありがとう!