38

JavaのConcurrentHashMapのソースコードを調べていたところ、次のコード行が見つかりました。

/*
 * The maximum number of times to tryLock in a prescan before possibly blocking on acquire in   
 * preparation for a locked segment operation. On multiprocessors, using a bounded number of  
 * retries maintains cache acquired while locating nodes.
 */
static final int MAX_SCAN_RETRIES =
              Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1

MAX_SCAN_RETRIES、ロックの取得中にエントリを検索する際に使用されます。私の質問は64、マルチプロセッサマシンの数はどのように決定されるのですか?数の背後にある理論を知っている人はい64ますか?

4

1 に答える 1

9

複数の CPU 間でロックの再試行を処理する場合、ロックをすばやく取得しようとする (スピンする) ことと、CPU が別のスレッドに切り替えて、取得されないロックでスピンする CPU 時間を無駄にしないようにすることとの間でバランスを取る必要があります。すぐにリリースされました。CPU がロックを取得するために許可される実際のスピン数は、システム全体の実際の速度と、クリティカル セクション内で通常実行されるコードの量の両方に大きく影響されます。

この問題は、同時実行性の最適化に関して、SMP システムの OS 設計に関連する停止問題やその他の多くの問題に深く根ざしています。この種の設計の選択は、通常、多くのアプリケーションで試行錯誤のアプローチによって解決されます。ただし、64 の選択は、実装者側の恣意的な呼び出しのように見えます (数は 2 の累乗です)。

残念ながら、この特定のコードにはバグがあり、制限があります。availableProcessors のドキュメントに「この値は、仮想マシンの特定の呼び出し中に変更される可能性があります」と記載されているため、ロックのスピン回数が多すぎる (カウントが > 1 から = 1 に移動する必要がある) か、少なすぎる (ビザの逆の場合)。MAX_SCAN_RETRIES が final であるため、実際にアプリケーションで並行性を調整する必要がある開発者がそれを行うことができないという点で制限があります (リフレクションを使用していくつかのトリックを実行することはできますが)。

于 2012-09-04T19:56:52.303 に答える