- PR -

[C#] コンストラクタの排他ロックの詳細

投稿者投稿内容
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-31 16:44
引用:

Thread.Sleep(2000)のコメントを外すと実行できる(ときがある)。


スレッドの割り当てに時間がかかり結果的にインスタンスの参照が出来上がってたということでありえると思います。
しかしながらメモリ上のコンストラクタが複数スレッドから非同期実行されてるわけではないですよね?

つまり

引用:

(2) 生成中のインスタンスにアクセスする処理は待機状態になり、
  コンストラクタが終了した後に目覚めて実行を継続する。


ここでいう待機状態というのはありえないですよね?
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-31 17:16
私の言い回しが悪すぎて誤解を与えたかもしれません。申し訳ありません。

引用:

ここでいう待機状態というのはありえないですよね?


はい。ありえません。

コンストラクタだからといってメソッドである事は変わりないので、待機してくれるなんてありえません。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-31 17:28
引用:

私の言い回しが悪すぎて誤解を与えたかもしれません。申し訳ありません。


いえいえ、お謝りになる必要はございません。
私もぼやっとしたものに答えが欲しくてかいてるだけです。

引用:

ここでいう待機状態というのはありえないですよね?


これはちょっと言い方が悪かったのですが、なちゃさんもおっしゃってるように
Newによりメモリ上に作成されるコンストラクタは必ず独自のエリアであり、
かつそのエントリに複数のコールが飛び込むことは無いですよね?
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-10-31 17:49
引用:

Newによりメモリ上に作成されるコンストラクタは必ず独自のエリアであり、
かつそのエントリに複数のコールが飛び込むことは無いですよね?


ここが少し理解が難しいです。
どういう状況を指しているでしょうか?

「インスタンス作成途中」という表現が不味かったかもしれません。
インスタンスが作成されるのは「コンストラクタの呼び出しが完全に完了した後」ですよね。

質問主さんが訊きたいのは、「コンストラクタの呼び出しがまだ途中の時に、別スレッドからそのインスタンスを指している参照を使えばどうなるか?」だと解釈しています。
で、単純に
「コンストラクタの呼び出しが完了していないのだから、インスタンスはまだない。なので、使えない」というのが私の考えです。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-10-31 18:28
引用:

Newによりメモリ上に作成されるコンストラクタは必ず独自のエリアであり、
かつそのエントリに複数のコールが飛び込むことは無いですよね?


この1行目は私もよく分からないです。
2行目は、まあ普通に考えてそれはそうですよね。

で、
引用:

質問主さんが訊きたいのは、「コンストラクタの呼び出しがまだ途中の時に、別スレッドからそのインスタンスを指している参照を使えばどうなるか?」だと解釈しています。
で、単純に
「コンストラクタの呼び出しが完了していないのだから、インスタンスはまだない。なので、使えない」というのが私の考えです。


インスタンスが存在する、というのをどのタイミングと考えているかによります。
インスタンスの構築が完了するのはもちろんコンストラクタ実行完了後ですが、
コンストラクタを実行している時点ではメモリの確保や初期化はすんでいるので、
呼び出そうと思えば呼び出してしまうことはできますよね?
※普通そういうことをするか、というのは別問題として。

たとえば、
コード:
public class ClassA
{
  public static ClassA hoge;
  public ClassA()
  {
    hoge = this;
    Thread.Sleep(10000);
  }
}


みたいなクラスを作成して、別スレッドからClassA.hogeを参照すれば、
まだコンストラクタを実行中のインスタンスを参照できてしまいます。
※実は試してないので、もしかして何らかの理由でできなかったらごめんなさい。

で、元質問者の方は、まだコンストラクタ実行中のインスタンスに対して
ほかのスレッドから何らかの処理を実行した場合、インスタンスがロック?
されているように考えていたんですよね。
※実際は、自動的に排他処理が行われるようなことはありませんが。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2005-10-31 23:09
引用:

ここが少し理解が難しいです。

質問主さんが訊きたいのは、「コンストラクタの呼び出しがまだ途中の時に、別スレッドからそのインスタンスを指している参照を使えばどうなるか?」だと解釈しています。


「インスタンス=メモリに存在している」ということからすると、「コンストラクタの途中」という状態のものの
参照が存在することがあるのか?という疑問でした。
最初の発言に先立ってシングルトンについて再確認しましたが、その他にそのような状況があるのかなって。

引用:

「コンストラクタの呼び出しが完了していないのだから、インスタンスはまだない。なので、使えない」というのが私の考えです。


私も同様です。Nothingが返ってくるんだろうなと。

どうもロックという言葉と参照変数っていうのがこびりついています。

>ひろしさん
すいません。勝手に盛り上がっちゃって。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-10-31 23:35
引用:

まどかさんの書き込み (2005-10-31 23:09) より:

「インスタンス=メモリに存在している」ということからすると、「コンストラクタの途中」という状態のものの
参照が存在することがあるのか?という疑問でした。私も同様です。Nothingが返ってくるんだろうなと。


コンストラクタの中でも基本的には自由に処理を記述出来ますよね。
メンバにアクセスするときなんかは、内部的に自分の参照を使用している訳です。

コンストラクタの呼び出しもとに参照が返されるのはコンストラクタ終了後ですが、
正常にアクセス出来るメモリ領域が確保される、つまり参照が存在出来るのは
それより前、コンストラクタ開始より前になるはずですね。

なので、コンストラクタ終了前に別スレッドからインスタンスにアクセスすることは、
やろうと思えば出来てしまうということです。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-01 12:44
引用:

なので、コンストラクタ終了前に別スレッドからインスタンスにアクセスすることは、
やろうと思えば出来てしまうということです。


なちゃんさんのコードを見て、確かにないことはないなぁと思いました。納得です。

#元質問者さんの意図から大きく外れた議論をしてしまい申し訳ありません。件は納得されたでしょうか・・・。

スキルアップ/キャリアアップ(JOB@IT)