3

書籍Java Concurrency in Practice、 Chapter 12.1 Testing for correctness、特にサブセクション 12.1.3 Testing safety (作成者が Bounded Buffer クラスのデータ競合の安全性をテストするためのテスト ケースを設定したい場合) から

あなたのテストが、あなたが思っていることを実際にテストすることを確実にするために、コンパイラーがチェックサム自体を推測できないようにすることが重要です。連続する整数をテスト データとして使用するのはお勧めできません。結果が常に同じになり、スマート コンパイラがそれを事前計算する可能性があるからです。

この問題を回避するには、テスト データをランダムに生成する必要がありますが、乱数発生器 (RNG) の選択が不適切なため、効果的なテストの多くが損なわれます。ほとんどの乱数ジェネレーター クラスはスレッド セーフであり、追加の同期が導入されるため、乱数生成によってクラスとタイミング アーティファクト間の結合が作成される可能性があります。

テスト入力の生成に乱数ジェネレーターを使用することに反対する著者の指摘が理解できません。具体的には、「乱数生成により、クラス間の結合が作成され、タイミング アーティファクトが発生する可能性がある」という行が明確ではありません。

  1. 彼がここで言及しているクラスとタイミング アーティファクトはどれですか?
  2. RNG はどのようなカップリングを作成できますか?
4

1 に答える 1

7

乱数生成はクラス間の結合を作成する可能性があり、タイミング アーティファクトは私には明確ではありません。

これは、次の文を考慮するとより明確になります。

ほとんどの乱数ジェネレーター クラスはスレッド セーフであるため、追加の同期が導入されるためです。

プログラムのタイミングを変更する可能性があるのはメモリ同期です。を調べるとRandom、内部で が使用されていることがわかります。AtomicIntegerこれを使用すると、テスト データの生成の一部として読み取りおよび書き込みメモリ バリアが発生し、他のスレッドがデータを参照する方法やアプリケーション全体のタイミングが変わる可能性があります。 .

彼がここで言及しているクラスとタイミング アーティファクトはどれですか?

スレッドを使用し、メモリ同期に依存するすべてのクラスが影響を受ける可能性があります。基本的に、それらが呼び出すすべてのスレッドとクラス。

RNG はどのようなカップリングを作成できますか?

@Bill the Lizard がコメントしたように、この本は、RNG を使用することで、プログラムのタイミングが RNG 同期に依存するか影響を受けると述べています。

ここでの本当の教訓は、プログラムに注入するテスト データは、可能であればプログラムのタイミングを変更してはならないということです。多くの場合、困難で不可能な場合もありますが、目標は、テストでアプリケーションの動作 (タイミング、入力、出力など) を可能な限りシミュレートすることです。

解決策として、同期されていない別の単純なランダム アルゴリズムを使用できます。また、事前に 10000 個の乱数 (または必要な数) を格納し、それらを同期せずに配布するクラスを生成することもできます。しかし、テストでメモリ同期を行ったクラスを使用することで、プログラムのタイミングを変更しています。

于 2013-09-11T17:45:19.893 に答える