2003年12月22日
川俣晶の縁側ソフトウェア技術雑記total 11790 count

C#のstaticコンストラクタが実行中に、他のスレッドから同じクラスのstaticメンバにアクセスがあったとき何が起こるか

Written By: 川俣 晶連絡先

 C#のstaticなコンストラクタは、staticなメンバやそのクラスのインスタンス作成に先んじて実行されます。これは、1プロセス上に1つしかない様々な資源の初期化に便利ではありますが。

 はたと不安になったことがありました。マルチスレッド環境だと何が起こるのでしょうか。たとえば、クラスCのstaticなメンバー変数Vにアクセスするスレッドが2つ走っていたとします。片方のスレッドがメンバー変数Vに最初にアクセスした時に、コンストラクタの実行が開始されますが、それが完了する前にもう1つのスレッドがメンバー変数Vにアクセスしたら何が起こるのでしょうか。

 C#言語仕様には特に何も書いていないので、おそらくstaticなコンストラクタの実行が完了されるまで全て待たされると思いましたが、100%の確信が持てません。

 というわけでテストプログラムを書いてみました。

using System;

using System.Threading;

namespace ConsoleApplication2

{

    public class TestClass

    {

        public static int A = 0;

        static TestClass()

        {

            Console.WriteLine("TestClassコンストラクタ called");

            Console.WriteLine("A(1)={0}",A);

            Thread.Sleep( TimeSpan.FromSeconds(3) );

            Console.WriteLine("A(2)={0}",A);

        }

    }

    class Class1

    {

        public static void ThreadProc1()

        {

            Console.WriteLine("ThreadProc1 called");

            TestClass.A ++;

            Console.WriteLine("A(3)={0}",TestClass.A);

        }

        public static void ThreadProc2()

        {

            Console.WriteLine("ThreadProc2 called");

            Thread.Sleep( TimeSpan.FromSeconds(1) );

            TestClass.A ++;

            Console.WriteLine("A(4)={0}",TestClass.A);

        }

        [STAThread]

        static void Main(string[] args)

        {

            Thread t1 = new Thread(new ThreadStart(ThreadProc1));

            Thread t2 = new Thread(new ThreadStart(ThreadProc2));

            t1.Start();

            t2.Start();

            t1.Join();

            t2.Join();

        }

    }

}

 このプログラムは、ThreadProc1が変数Aにアクセスしてstaticなコンストラクタを起動させ、その実行中にThreadProc2が変数Aの書き換えに行く、というものです。もし、正しく全てのアクセスがコンストラクタ実行完了まで待たされていれば、A(2)=0という結果を得るはずです。コンストラクタ実行中に変数を書き換えることができたなら、A(2)=1という結果になるはずです。

 実行結果は以下の通りになりました。(.NET Framework 1.1環境下)

ThreadProc1 called

TestClassコンストラクタ called

A(1)=0

ThreadProc2 called

A(2)=0

A(3)=1

A(4)=2

 というわけで、結果は好ましいものでした。

 マルチスレッド環境でも、staticなメンバーへのアクセスは、staticなコンストラクタの実行が完了されるまで遅延されているということですね。

Facebook

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

http://mag.autumn.org/tb.aspx/20031222134837
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.34 (Alpha-Test) Copyright (c) 2004-2018 Pie Dey.Co.,Ltd.