...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

synchronized その2

import std.stdio;
import core.thread;

class SharedData
{
	public int v;
	public synchronized void increase() // 同期関数に変更 (2)
	{
		// 同期関数は次のようなsynchronized(this)と等価 (1)
		//synchronized(this){
		int a = v;
		for(int i; i<1000000; i++){} // wait
		v = a + 1;
		//}
	}
}

class IncrementThread : Thread
{
	private shared(SharedData) sd;
	public this(shared(SharedData) sd)
	{
		this.sd = sd;
		super(&f);
	}
	private void f()
	{
		sd.increase(); // 同期関数はshared修飾されたオブジェクトからしか呼べない (3)
	}
}

void main()
{
	// 全部のスレッドで共有するデータ
	// sharedオブジェクトは非sharedオブジェクトと相互に代入できないので全部shared(SharedData)型に変更 (4)
	auto sd = new shared(SharedData);
	// 10個のスレッドを次々に作って実行開始
	Thread[] threads;
	for(int i; i<10; ++i)
	{
		auto t = new IncrementThread(sd);
		threads ~= t;
		t.start();
	}
	// すべてのスレッドが終了するのを待つ
	foreach(t; threads)
	{
		t.join();
	}
	// インクリメント結果を表示
	writeln(cast(int)sd.v); // バグ?回避のキャスト
}

うーん.
SharedObjectがスレッドローカルオブジェクトじゃないから元々sharedが必要ないので例としてあんまり.