/* Page prose (ja) */
"DataRace" = "# バグの正体: data race\n\n**data race** とは、二つのスレッドが同じメモリの一部に同時にアクセスし、そのうち少なくとも一方が書き込みをしている状態のことです。**競合状態** はより広いファミリーで、結果が並行作業の予測できない*タイミング*に依存するあらゆるバグを指します。すべての data race は競合状態ですが、すべての競合状態が直接メモリに関わるわけではありません。この章では、その二つは一緒に旅をします。\n\nこちらが銀行です。一つの口座、一つの残高。千人の窓口係がそれぞれ `1` の入金を一度ずつ記録します。残高はちょうど `1000` で終わるはずです。";
"DataRace-2" = "**実行して確認:** コードを数回実行してみましょう。`Final balance: 647 (expected 1000)` のような表示が出ます。もう一度実行すると `581`。また `621`。また `658`。**数値は実行のたびに変わり、たいてい間違っています。** そのコードのどの行もスペルミスはしていません。ロジック（読み取り、1を足し、書き戻す）は*一人*の窓口係にとってはまったく正しいものです。千人が同時にそれを行うために崩れてしまうのです。\n\n二人の窓口係が衝突する様子を追ってみましょう。\n\n1. 窓口係 A が `balance` を読む → `500`。\n2. 窓口係 B が `balance` を読む → `500`（A はまだ書き戻していません）。\n3. 窓口係 A が `501` を書く。\n4. 窓口係 B が `501` を書く。\n\n入金は二回起きました。残高は*一つ*だけ増えました。窓口係 B の1ドルは消えてしまいました。**更新の消失**（lost update）です。これがバグのすべてです。`balance += 1` はアトミックに見えますが、実際には読み取り、そして書き込みで、その間に隙間があります。並行キューでは、別の窓口係がその隙間に滑り込めます。（上で三つの明示的な行に分割したのは、隙間を広げて毎回見えるようにするためです。一行の `account.balance += 1` もまったく同じ欠陥を持っており、更新を失う頻度がわずかに少ないだけです。）\n\n* callout(試してみよう): ループを `1_000` から `10` 人の窓口係に減らして、数回実行してみましょう。残高は同じくらいの頻度で間違ったままになりますか？\n\n[前へ](@previous)  |  2 / 9 ページ  |  [次へ: 見つけにくい理由](@next)";
