1
public void Remove(T item)
{
    locker.EnterWriteLock();        
    try
    {
        list.Remove(item);
    }
}

上記はインスタンスクラスのメソッドです。インスタンスがであるとしましょうmyObject。上記のフラグメントに関して、私の質問はこれです:

スレッド1の呼び出しmyObject.Remove(A)
スレッド1が実行されlocker.EnterWriteLock()ます。

2つの呼び出しをスレッド化しますmyObject.Remove(B)

スレッド1はtryブロックに入り、を実行しlist.Remove()ます。

itemこの時点での価値は何ですか?つまりlist.Remove()、パラメータとしてAまたはBを使用して呼び出されますか?

4

6 に答える 6

4

各スレッドには独自のコール スタックがあり、メソッドの引数はそのスタックに格納されます。スタックはスレッド間で共有されません。

Removeスレッド 1 のスタックには、が呼び出され、"A" または "A" への参照が含まれている ことを示す行があります(値型か参照型かによって異なります)。

Removeスレッド 2 がメソッドに入ると、独自の呼び出しスタック (スレッド 2 の実行中はスレッド 1 のスタックは使用されません) があり、項目 "B"の開始を示す行があります。次に、そのスレッドは中断され、そのコール スタックは使用されず、スレッド 1 に戻ります。ここで、項目 "A" はコール スタックにあるものです。

将来のある時点で、スレッド 2 が再アクティブ化され、コール スタックに項目 "B" が含まれます。

于 2013-01-08T22:56:00.620 に答える
1

メソッドの引数は、メソッドを呼び出すスレッドのスタックに割り当てられます。したがって、すべてのスレッドには独自の引数があり、それらは互いに影響しません。

于 2013-01-08T22:55:42.940 に答える
0

ここでロックする必要があるのはlist変数だと思います。メソッドを呼び出していますがRemove、このlist変数がスレッドセーフではないタイプの場合、たとえば、このメソッドが同じインスタンス(フィールドが存在する場所)List<T>の複数のスレッドから同時に呼び出されると、問題が発生する可能性があります。 。メソッドの引数に関する限り、メソッドのコンテキスト内でスレッドセーフについて話すのは難しいです。myObjectlist

于 2013-01-08T22:52:31.140 に答える
0

.Net は、パラメーターに対する継承ロックを提供しません。ただし、list.Remove(item)変更は行われずitem(標準System.CollectionsまたはSystem.Collections.Generic実装であると仮定)、同じメソッドを異なる引数で 2 回呼び出すと、1 つではなく 2 つのコピーitem(メソッド呼び出しごとに 1 つ) が作成されます。

代わりに、ほとんどのクラスのインスタンス メソッドがスレッド セーフであることが保証されていないため、list をロックします。

于 2013-01-08T22:55:05.850 に答える
0

locker.EnterWriteLock();スレッド 2 はスレッド 1 の実行を待機しますlocker.ExitWriteLock();

したがって、スレッド 2 はlist、スレッド 1 の呼び出しの前にアクセスできません。locker.ExitWriteLock();

parameter について心配する場合はitem、それがスタックを通過し、各スレッドに独自のスレッドがあることを確認してください。したがって、item実際には別のスレッドで「置き換える」ことはできません...

したがって、答えは次のとおりです。スレッド 1 がlocker.EnterWriteLock();スレッド 2 の前に呼び出された場合、スレッド 2 のA前に削除されBます。

于 2013-01-08T22:55:17.507 に答える
0

の値がパラメータitemの値になりAます。

locker.ExitWriteLockが実行されて初めて、スレッド 1 がブロックを使用できるようになります。

于 2013-01-08T22:56:11.753 に答える