このコードを見てみましょう。
java.util.bitset。スレッドT1 = newスレッド(new runnable(){public void run(){try {latch.await(); swree.sleep(1000);} catch(Exception ex){} bs.set(1);});スレッドT2 = newスレッド(new runnable(){public void run(){try {latch.await(); swree.sleep(1000);} catch(例外e){} bs.set(2);}}) ; Start(); :}}問題は、このコード出力の結果は何ですか?崩壊したJVMでも、どのような結果が出ますか?
このプログラムが何をするかを見てみましょう。
次に、これらの動作を確認するためにいくつかのテストケースを構築する必要があります。明らかに、そのうちの1つはこの例を実行し、結果を観察し、許容可能な出力に関する2番目の結果に答えることができます。
慎重さは偶然になる可能性があります
幸いなことに、ツールを使用できます。 JCStressは、このような問題を解決するためのテストツールです。
JCStressが認識できるフォームとして、テストケースを簡単に書くことができます。実際、それは私たちのためにさまざまなインターフェイスを準備しています。この例では、2つのスレッドが一緒に実行されます。
Actor2_arbiter1_teest <bitset、booleanresult2>インターフェイスを使用します。実行するにはJava 8 JVMを見つける必要がありますが、今ではこれは問題ではありません。
以下の実装を見てください。
Public Class AnexampletestはActor2_arbiter1_test <biteset、booleanresult2> {@override public void actor1(bitset s、booleanresult2 r){s.set(1);} @override public void actor2(bitset s、booleanresult2 r){S.Set(2 2 );} @Override public void arbiter1(bitset s、booleanresult2 r){r.r1 = s.get(1); ;
このテストを実行すると、コントロールはこれらのアクションを駆動する要因のすべての可能な組み合わせを取得するためにあらゆる種類のトリックを試みます:並列または非合併、負荷検出はありません。多くの場合、何度も何度も、したがって、すべての可能な結果が記録されます。
並列コードがどのようにオンになっているかを知りたい場合、これは虚ろな考えを掘り、自分よりもすべての詳細を考えるより良い方法です。
さらに、JCSTRESSの制約によってもたらされる包括的な利便性を使用するには、そうするために可能な結果を説明する必要があります。
<test name = "org.openjdk.jcstress.tests.custom.anexampletest"> <貢献by bits-by> <bitsetがうまく機能している場合、 > match> [true、true] </match> <expect>容認> <説明>すべての更新が無傷であることを確認します/expect> <説明> t2の結果> </case> <match> [false] </match> <expect> equipt> <説明> t1 > </case> <nmatched> <exped>禁止</exten> <説明>他のすべてのケースは> </untally> </test>の説明を受けています
今、私たちはこの獣が次のコマンドラインを使用してテストを開始する準備ができています。
java -xx:+lockdiagnosticvmoptions -xx:+whiteboxapi -xx:-resterictcontended -jar tests -custot/target/jcstress.jar -t = "。*anexampletestest"
結果はエレガントなレポートです。
予想される結果を得ることができるだけでなく、両方のスレッドが自分の位置を設定しているだけでなく、競争状態にも遭遇し、1つのスレッドが別のスレッドの結果をカバーすることは明らかです。
そのようなことを見たとしても、「山の人々が自分のトリックを持っている」という穏やかなメンタリティを持っている必要がありますよね?
ちなみに、このコードを変更する方法を考えている場合、答えはJavadocのBitsetクラスを慎重に読み、スレッドセキュリティではなく、外部同期が必要であることを認識することです。これは、同期ブロックの設定値を増やすことで簡単に実現できます。
同期(bs){bs.set(1);}