プロデューサが消費者が消費するよりもはるかに速い生産者 - 消費者シナリオがあります。一般的には、プロデューサ/コンシューマシナリオが最も遅いコンポーネントほど高速に動作するため、ソリューションはプロデューサをブロックすることです。私たちのアプリケーションは、消費者が後で追いつくのに十分な時間を提供するので、生産者のスロットルまたはブロックはではなく、です。ここで速いプロデューサ、遅いコンシューマのためのJavaの "階層化されたキュー"実装
は、より一般的なシナリオ対我々のアプリケーションでは、完全な「フェーズ」を描いた図です:
Our Application Common Scenario
2N +--------+--------+
|PPPPPPPP|oooooooo| P = Producer
|PPPPPPPP|oooooooo| C = Consumer
N +--------+--------+ N +--------+--------+--------+ o = Other Work
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo| N = number of tasks
|CPCPCPCP|CCCCCCCC| |CPCPCPCP|CPCPCPCP|oooooooo|
------------------- ----------------------------
0 T/2 T 0 T/2 T 3T/2
アイデアが生産を阻害しないことにより、スループットを最大化することです。
私たちのタスクが動作するデータは簡単にシリアライズされるので、すぐには満たせないすべてのタスクをスピルアップするためのファイルシステムソリューションを実装する予定です。
私はメモリが不足しないように最大容量のBlockingQueue
でJavaのThreadPoolExecutor
を使用しています。問題は、メモリにキューイングできるタスクがすぐに実行されるような「階層型」キューを実装することです。それ以外の場合は、データがディスク上にキューイングされます。
私は2つの可能な解決策を作ってみた:
- を基準として
LinkedBlockingQueue
またはArrayBlockingQueue
実装を使用して、ゼロからBlockingQueue
を実装します。これは、標準ライブラリの実装をコピーし、ファイルシステムの読み書きを追加するのと同じくらい簡単です。 - 標準
BlockingQueue
の実装を継続し、データを格納するために別のFilesystemQueue
を実装し、ファイルをデキューするために1つ以上のスレッドを使用してRunnable
を作成し、ThreadPoolExecutor
を使用してエンキューします。
これらのいずれかが妥当であり、潜在的により良いアプローチですか?