我写了两个lock-free update
辅助方法,灵感来自Joseph Albahari& Marc Gravell
查看第二个实现,为什么我在第一个实现中需要SpinWait
?一个优于另一个的优点/缺点是什么?
请注意,这个问题不是关于SpinWait
做什么,而是关于这两种方法在执行方面的差异。
public static void LockFreeUpdate1<T>(ref T field, Func<T, T> updater) where T : class
{
var spinner = new SpinWait();
T snapshot;
while (true)
{
snapshot = field;
if (snapshot.Equals(
Interlocked.CompareExchange(ref field, updater(snapshot), snapshot))) { return; }
spinner.SpinOnce();
}
}
public static void LockFreeUpdate2<T>(ref T field, Func<T, T> updater) where T : class
{
T snapshot;
do
{
snapshot = field;
} while(
snapshot.Equals(
Interlocked.CompareExchange(ref field, updater(snapshot), snapshot)));
}