銀行クラスをスレッドセーフに扱う
どこでどのような競合を起こしうるのか想像するのが難しい.
このようにスレッドセーフに使えるクラスを「スレッドコンパチブルである」という.
import std.stdio; import core.thread; import core.sync.mutex; class Bank { private int money_; void payin(int m) { money_ += m; } void payout(int m) { money_ -= m; if (money_ < 0) { // ここには来ない throw new Exception("pay out exception."); } } int money() @property { return money_; } } void main() { auto bank = new Bank; auto tg = new ThreadGroup; bool isRunning = true; auto mutex = new Mutex; // 100ずつ出金する人 tg.create = { while (isRunning) { try { synchronized (mutex) { if (bank.money >= 100) // 残金を確認して { foreach (_; 0..10000){} // 異常が起こりやすいように待つ // お金があるときだけ出金するはず? bank.payout(100); } } } catch (Exception e) { isRunning = false; // 両方のスレッドを終了する throw e; } } }; // 100ずつ入金する人 tg.create = { while (isRunning) { synchronized (mutex) { bank.payin(100); } } }; // スレッドを回す tg.joinAll(); }