静的クラスの静的メンバーの初期化に問題があります。私の知る限り、初期化は 1 回だけなので、この操作がスレッド セーフであることを確認するために、同時実行で fooList.Add(...) を実行するときにこの変数をロックします。
internal static class ObjectA
{
private static object _lockAdd = new object();
public void functionA()
{
lock (_lockAdd)
{...
私はいくつかの奇妙な状況に遭遇したので、log4net によって _lockAdd のハッシュコードを書くことにしました。驚いたことに、これは私が観察したものです:
【INFO】【2012-04-20 15:26:44,080】【thread12】_lockAddさんのハッシュコード(51755728)...
【INFO】【2012-04-20 15:26:58,624】【thread16】_lockAddのハッシュコード(31071611)...
ご覧のとおり、2 つの '_lockAdd ' アドレスが異なります。なぜですか、それとも静的メンバーに関する私の理解が間違っているのでしょうか? 操作が静的クラスにある場合、スレッドセーフを確保するにはどうすればよいですか?
偽のコードのエラーで申し訳ありませんが、これは私の実際のコードです:
internal static class UtilExtension
{
private static object _lockAdd = new object(); //initial twice ? why?
public static void DoAdd(this Type entityType)
{
if (!Pools.Has(entityType))
{
lock (_lockAdd)
{
if (!Pools.Has(entityType)) //insure operation below is thread safe
{
// i find something wrong in concurrency,so i log the _lockAdd's hashcode,
// and then i found it's hashcode is different( in my opinion, it means not the same variables )
LogUtil.Info(_lockAdd.GetHashCode().ToString());
//... do fooList.Add(...)
}
}
}
}
}