/* Page prose (ja) */
"OneTaskAtATime" = "# actor は一度に 1 つのタスクだけを入れる\n\nまず、問題をもう一度。これは[並行処理の落とし穴](Concurrency%20Hazards.playgroundchapter/Overview)の章のバグを、最も単純な形にしたものです。素朴なクラスが残高を保持し、多くの並行する入金がそれを奪い合って競合します。\n\n```swift\nfinal class UnsafeLedger {\n    var balance = 0\n\n    func deposit(_ amount: Int) {\n        balance += amount   // read, add, write (not atomic)\n    }\n}\n```\n\nこの `balance += amount` は実際には*3 つ*のステップです。現在の値を読み、それに足し、書き戻す。2 つのタスクが同時に `0` を読むと、両方が `1` を書き込み、1 件の入金が失われます。1000 件の並行入金を実行しても、`1000` になることはめったにありません。\n\nSwift 6 では、その `UnsafeLedger` を並行するタスク間で実際に共有しようとすると、**コンパイラが止めてくれます**。素朴な可変クラスは共有しても安全ではないため、コンパイルできません。これはコンパイラが正しいツールを指し示しているのです。そのツールが actor です。\n\n**actor** はクラスのような参照型で、その可変状態は**一度に 1 つのタスク**からしか触れられません。actor は自身の状態へのすべてのアクセスをシリアル化するので、先ほどの読み-足し-書きが重なることは決してありません。`class` を `actor` に置き換えます（ついでに引き締めるために、`balance` を `private(set)` にして、actor 自身のメソッドだけが変更できるようにしましょう。外部のコードは引き続き読み取れます）。\n\n```swift\nactor Ledger {\n    private(set) var balance = 0\n\n    func deposit(_ amount: Int) {\n        balance += amount\n    }\n}\n```\n\nこれで修正は完了です。`deposit` の呼び出しは、いまや自動的にシリアル化されます。あるタスクが `deposit` の中にいる間、ほかのすべてのタスクは順番を待たなければなりません。設定するキューもなく、覚えておくことも何もありません。タスクグループ（[Task Groups](Task%20Groups.playgroundchapter/Overview)の章）を使って、1000 件の並行入金で叩いてみましょう。";
"OneTaskAtATime-2" = "**実行して確認:** 最終残高は **`1000`。毎回です。** 何度も何度も実行してみてください。決してずれません。1000 件の入金がすべて着地しました。更新を予測できない形で失うクラス版と比べてみてください。actor は競合を保証に変え、しかもロックを 1 つも書きませんでした。\n\n* callout(試してみよう): ループを `1...10_000` 件の入金まで増やしてみましょう。最終残高は、それでも毎回きっかり正しく出ますか？\n\n> これは本書の前半でのシリアルキューによる修正とは異なります。あそこではすべてのアクセスを 1 つのキューに通すことを*自分で選び*、一貫性を保つことを何も強制してくれませんでした。1 つでも直接アクセスがはぐれると競合が再び現れました。actor はその保護を型の一部にします。シリアル化を飛ばして `balance` に到達する方法はなく、コンパイラがあなたの代わりに確認してくれます。\n\n[前へ](@previous)  |  2 / 7 ページ  |  [次へ: actor 分離](@next)";
