我试图了解 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 的最新值,而无需 Interlocked?