3

簡単な質問です。割り当てアトミックの下にあります:

object [] table = new object[10]
...
table[3] = 10; //is it atomic ?
...
4

3 に答える 3

3

I am assuming OP means 'thread safe' when talking about atomicity.

A write operation is not atomic only if it is possible that another thread can read partially written value.

If object [] table is local to a method, each thread will get their own table and hence any operation on the table will be atomic.

Going forward I am assuming that table is shared across threads.

OP has defined table as an array of object. Hence table[3] = 10 involves boxing.

Even though table[3] = 10 represents a chain of instructions, this operation is atomic because this will eventually be writing the 'address' of the boxed instance (Current CLR implementation do represent object reference using memory address) and addresses are of the natural word size of the machine (i.e. 32 bit on 32 bit machines and 64 bit on 64 bit machines). Please note that even though above explanation is based on current CLR implementation, atomicity of reference writing is guaranteed by specs. The operation of boxing and the boxed instance itself are local to the thread and hence there is no way that another thread can interfere in that. Going by same reasoning even if a value exceeding the word size (for e.g. Decimal) was being written, the operation would have been atomic (due to boxing). It must be noted here that the above argument holds only if the value being written has already been obtained in a thread safe manner.

Had no boxing been involved, then the usual rules of word size writes (or sizes lesser than the word size, owing to memory alignment) being atomic holds.

于 2013-08-23T08:15:30.067 に答える
2

table[3] = 10;用語全体がアトミックであることを真剣に疑っています。一部のデータ型への単一の読み取りまたは書き込みはアトミック配列アクセスですが、ほとんどの場合そうではありません。

あなたの例のILコードは

IL_0001:  ldc.i4.s    0A 
IL_0003:  newarr      System.Object
IL_0008:  stloc.0     // table
IL_0009:  ldloc.0     // table
IL_000A:  ldc.i4.3    
IL_000B:  ldc.i4.s    0A 
IL_000D:  box         System.Int32
IL_0012:  stelem.ref

インデックスが IL_000A にロードされ、次に int のボックス化が IL_000D で発生し、最後にボックス化された値が IL_0012 に格納されていることがわかります。

これらの命令の個々はアトミックかもしれませんが、それは make の一連の命令がアトミックであることを意味しませんtable[3] = 10;

于 2013-08-23T06:54:43.840 に答える