マルチスレッドのデザパタ本を読みながら、サンプルをGo言語で書きなおしている

こんにちは。最近、毛布を買って堕落に一歩近づいてしまったきたけーです。

最近、Go言語を触っています。Go言語の魅力はgoroutineですよねー ... ... ...
はい、マルチスレッドのプログラムをまったく書いたことのないゆとりで本当にすいません。

ということで、「Java言語で学ぶデザインパターン入門 マルチスレッド編」を読みながら、マルチスレッドのプログラムのデザインパターンについて学び始めました。

ただ、読むだけではしょうがないので、サンプルをGo言語で書きなおしています。

Channelを利用した排他制御

gist7153102

Producter-Consumerパターンを利用した複数のスレッドの協調

これ、待ち行列のシミュレーションのプログラムが簡単に書けると思うんですけどどうでしょう。

Javaデザパタ本 マルチスレッド編のsection5。 ProducerConsumerパターン

Read-Write Lockパターン

Javaデザパタ本 マルチスレッド編 section6 「read-write lockパターン」

書いていてあれこれ思ったこと

string型について

string型はバイト値の集まりです。
string型から一文字だけのstring型の値を得たいとき、マルチバイト文字かどうかで取得の方法が変わります。
例えば、"abcde"から先頭の「a」の文字列を新しく得るときはこんなかんじです。

newStr := string("abcde"[0]) // => "a"

これがUTF-8のマルチバイト文字だとこう書かなければいけません。

newStr := string("おやおや"[0:3]) // => "お"

スライスで3バイト分取得してstringにキャストしています。

ちなみに文字列から任意の文字列のインデックスを探すときはstringsパッケージのIndex関数を使います。

index := strings.Index("おやおや", "や")) // => 3
fmt.Println("おやおや"[index:index+3]) // => "や"

time.Sleepに渡す型

time.Sleep関数の引数に渡す型はtime.Duration型です。例えば、ランダムに得たint64型の値を使う場合は以下のようにtime.Duration型に変換する必要があります。

time.Sleep(time.Millisecond*time.Duration(random.Intn(1000)))