長年書類を書き続けて待ち続けた末に、ついに銀行の免許を取得しました。これで正式に、自分の銀行を開く資格を得たことになります。やった!
まず取りかかるのは、ITシステムを動かすことです。1日がんばったおかげで、もう口座の開設と閉鎖、そして引き出しと預け入れまでできるようになりました。
テストを書くのは面倒だったので、友達に声をかけてシステムのテストを手伝ってもらいます。ところが、始めてからわずか5分で、友達の一人がお金がなくなったと言い出しました! 自分のコードにバグはないと確信していますが、念のためログを調べて原因を探ることにします。
ああ、やっぱり。疑ったとおり、悪いのは友達のほうでした! その友達はテスト用の認証情報を別の友達と共有していて、二人で結託して同じ口座から_並行して_預け入れと引き出しを繰り返していたのです。いったい誰がそんなことをするでしょうか?
誰かが同時に自分の口座にアクセスするのは物理的に_不可能_だと主張しますが、友達は得意げに、銀行のルールではそれをサポートすることが_必須_だと告げます。つまり、並行処理をサポートしなければ、サービス開始のゴーサインは出ないということです。ため息をつきながら、明日取りかかろうと心にメモします。これでサービス開始は_少なくとも_あと1日は延びますが、まあ仕方ありません…
この課題では、口座の開設・閉鎖、出金、入金に対応する銀行口座を実装します。
銀行口座には、インターネット、携帯電話、自動引き落としなど、さまざまな方法でアクセスできます。そのため、作成する銀行ソフトウェアは、複数のスレッドやプロセス(呼び方はプログラミング言語によって異なります)から、口座に安全に並行アクセスできるようにしなければなりません。 たとえば、多数の入金と出金が並行して行われることがあります。残高を読み取ってから新しい残高を設定するまでの間に、競合状態が起きないようにする必要があります。
口座は閉鎖できる必要があります。閉鎖された口座に対する操作は、必ず失敗しなければなりません。
この演習では、複数のスレッドから安全にアクセスできる可変状態を扱います。Scalaには、可変状態を保護するためのさまざまな方法があります。Javaの並行処理に慣れているエンジニアなら、ScalaでJavaの並行処理サポート、たとえばJavaのsynchronizedブロックを利用できます。
Scalaで可変状態を実現する方法は2つあります。varを使うか、可変オブジェクトを使うかです。
ここでよくある間違いは、次の2つです。
varと可変オブジェクトを併用しないようにしましょう。どちらか一方で十分で、両方を使う必要はありません。varや可変オブジェクトを外部に公開しないようにしましょう。それらをprivateにして、値を返す前に可変オブジェクトを不変に変えておきましょう。