Interlocked.Exchangeの正しい使用法を理解しようとしているので、追加および削除機能を備えた単純なソート済みLinkedListを実装しています。
これがスレッドセーフリストではなかった場合、明らかに挿入ポイントを見つけるには、次のようなものを使用して、挿入する正しいポイントを見つけてから、新しいノードを見つける必要があります。
public void Insert(int newValue)
{
var prev = _header;
Node curr = _header.Next;
while(curr != null && curr.value > newValue )
{
prev = curr;
curr = curr.Next;
}
var newNode = new Node(newValue, curr);
prev.Next = newNode;
}
以下は、同時リストに対してこれを行う必要がある方法についての私の見解です。Interlocked.Exchangeが多すぎますか?これがなくても、インサートはスレッドセーフですか?数百または数千のインターロック操作がパフォーマンスの低下を引き起こしますか?
public void InsertAsync(int newValue)
{
var prev = _header;
Node curr = new Node(0, null);
Interlocked.Exchange(ref curr, _header.Next);
while (curr != null && curr.value > newValue)
{
prev = Interlocked.Exchange(ref curr, curr.Next);
}
//need some locking around prev.next first, ensure not modified/deleted, etc..
//not in the scope of this question.
var newNode = new Node(newValue, prev.Next);
prev.Next = newNode;
}
たとえば、curr = curr.nextはアトミック読み取りであることを理解していますが、特定のスレッドがインターロックなしでcurr.nextの最新の値を読み取ることを確認できますか?