Single Threaded Execution

Java言語で学ぶ デザインパターン』のSingle Threaded Executionをgoでやってみた。
スレッドは、goroutineで実装してみたが、上手くいかない。同時に動いているはずのgoroutineが1つのGateクラスのインスタンスを取り合うはずなんだが、取り合ってくれない。

夕食のおかずは、ベーコンとアスパラガス、ブロッコリー、ミディトマト、玉ねぎのオイスターソース炒め、ごぼうとコンニャクのきんぴら、かますの干物。

package main;

import "fmt";

// Gate class
type Gate struct {
	counter int;
	name string;
	address string;
}

func (gate *Gate) init() {
	gate.counter = 0;
	gate.name = "Nobody";
	gate.address = "Nowhere";
}

func (gate *Gate) check() {
	if gate.name[0] != gate.address[0] {
		fmt.Printf("***** BROKEN ***** No.%d: %s, %s\n", gate.counter, gate.name, gate.address);
	}
}

func (gate *Gate) Pass(name string, address string) {
	gate.counter++;
	if gate.counter % 1000 == 0 {
		fmt.Printf("counter = %d, name = %s, address = %s\n",
			gate.counter, gate.name, gate.address);
	}
	gate.name = name;
	gate.address = address;
	gate.check();
}

// UserThread class
type UserThread struct {
	gate *Gate;
	myname string;
	myaddress string;
}

func (userThread *UserThread) init(gate *Gate, myname string, myaddress string) {
	userThread.gate = gate;
	userThread.myname = myname;
	userThread.myaddress = myaddress;
}

func (userThread *UserThread) run() {
	fmt.Printf("%s BEGIN\n", userThread.myname);
	for {
		userThread.gate.Pass(userThread.myname, userThread.myaddress);
	}
}

// main
func main() {
	gate := new(Gate);
	alice := new(UserThread);
	alice.init(gate, "Alice", "Alaska");
	bobby := new(UserThread);
	bobby.init(gate, "Bobby", "Brazil");
	chris := new(UserThread);
	chris.init(gate, "Chris", "Canada");
	go alice.run();
	go bobby.run();
	chris.run();
}