ブロッキング キューを使用するとブロックが多すぎて速度が低下していると思われます。
あなたは間違っていると思います。次のテスト プログラムは、ArrayBlockingQueue を介して 100 万個の整数をプッシュします。
public class ArrayBlockingQueuePerfTest {
int maxi = 1000000;
ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1000,
true);
Thread sender = new Thread("sender") {
public void run() {
try {
for (int i = 0; i < maxi; i++) {
queue.offer(i, 1, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
};
};
Thread receiver = new Thread("receiver") {
public void run() {
try {
int count = 0;
long sum = 0;
while (count < maxi) {
sum += queue.poll(1, TimeUnit.SECONDS);
count++;
}
System.out.println("done");
System.out.println("expected sum: " + ((long) maxi) * (maxi - 1) / 2);
System.out.println("actual sum: " + sum);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
};
};
public ArrayBlockingQueuePerfTest() {
sender.start();
receiver.start();
}
public static void main(String[] args) {
new ArrayBlockingQueuePerfTest();
}
}
私のラップトップでは、数秒で終了します。したがって、パフォーマンスのボトルネックがどこにあっても、必要以上に少なくとも 3 桁高いスループットを処理できるのは ArrayBlockingQueue ではありません。別の言い方をすれば、実行時間がまったくかからないスレッド通信アプローチを見つけたとしても、プログラムの速度はせいぜい 0.1% しか向上しないということです。
これと他のすべてのパフォーマンスの問題についての教訓: 既存のコードのパフォーマンスの問題に取り組むときの最初のステップは、通常、コードのどの部分が遅いかを測定することです。プロファイラーは、このタスクを大幅に簡素化します。