私はかつて、いわゆる非アトミックおよびアトミック(VBではインターロック)操作に関する非常に優れた説明を読み、それを要約しようとします。
Normal "non-atomic" operations consist of several steps
->他のスレッドはそれらのstrepsの間に動作できます
"Atomic" operations consist of one only one step
->アトミック操作が処理されている間、他のスレッドは作業を実行できません。アトミック操作は常に全体として処理されます
インターロックされたクラスは、そのようなアトミック操作のコレクションであるため、定義上、スレッドセーフです。複数のスレッドが同じ変数に対して読み取りおよび書き込み操作を実行している場合でも、これらの操作は完全にスレッドセーフです。
それでも、これらのスレッドセーフコマンドの組み合わせは、アトミック操作の間に競合状態が発生する可能性があるため、安全ではない可能性があります。
したがって、たとえば2つの変数を比較してから小さい方の変数をインクリメントする場合、それら自体の単一の操作(interlocked.compare、interlocked.increment)であっても、これはスレッドセーフではありません。ここでも、同期ロックを使用する必要があります。
その制限を除いて、インターロックの「隠れた悪い面」はありません。
a =5のレース条件の1つの例:
Thread1: a+=1
Thread2: a+=2
--> supposed to be 8, but can be only 6 or 7,
but can also be 6 or 7 depending on which thread wins the race
オプション1:
T1 step 1: read 5
T1 step 2: add 1 = 6
T1 step 3: write 6
T2 step 1: read 6
T2 step 2: add 2 = 8
T2 step 3: write 8
--> is 8 as supposed
またはオプション2:
T1 step 1: read 5
T2 step 1: read 5
T1 step 2: add 1 = 6
T2 step 2: add 2 = 7
T2 step 3: write 7
T1 step 3: write 6
--> is only 6
またはオプション3:
T1 step 1: read 5
T2 step 1: read 5
T1 step 2: add 1 = 6
T2 step 2: add 2 = 7
T1 step 3: write 6
T2 step 3: write 7
--> is only 7
interlocked.incrementを使用:
オプション1:
T1 step 1: read 5, add 1, write 6
T2 step 1: read 6, add 2, write 8
またはオプション2:
T2 step 1: read 5, add 2, write 7
T1 step 1: read 7, add 1, write 8
->すべての場合でa=8と想定される、スレッドセーフなソリューション
ここに投稿されたすべての質問は、この簡単な例を疑わしいコードに適用することで解決できます。
これがこのトピックをグーグルで検索する他の人々に役立つことを願っています。ジャニス