c#中 Interlocked类用来保证将对整数的基本操作为原子操作。
我们在高级语言中的写的语句,绝大部分都不能直接对应到机器指令上去,编译器在翻译的过程中,会将高级语句转化为一系列的低级指令。这样在高级语言中的一条语句就可能对应多条指令的操作。
在多线程的环境中,这样的高级语句的执行效果就会出现一些问题,看上去好像一条语句只执行了一半。对于最简单的操作,例如两个数相加、交换、加一、减一等操作, .net提供了Interlocked类来保证这些基本操作的原子性。
我们也可以使用其它的用于线程同步的类来保证,但是在简单的情况下,使用Interlocked会更方便,主要是系统开销更小。
下面是Interlocked的接口:
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
namespace System.Threading
{
// 摘要:
// 为多个线程共享的变量提供原子操作。
public static class Interlocked
{
// 摘要:
// 以原子操作的形式,添加两个 32 位整数并用两者的和替换第一个整数。
//
// 参数:
// location1:
// 一个变量,包含要添加的第一个值。两个值的和存储在 location1 中。
//
// value:
// 要添加到整数中的 location1 位置的值。
//
// 返回结果:
// 存储在 location1 处的新值。
[ReliabilityContract(3, 2)]
public static int Add(ref int location1, int value);
//
// 摘要:
// 以原子操作的形式,添加两个 64 位整数并用两者的和替换第一个整数。
//
// 参数:
// location1:
// 一个变量,包含要添加的第一个值。两个值的和存储在 location1 中。
//
// value:
// 要添加到整数中的 location1 位置的值。
//
// 返回结果:
// 存储在 location1 处的新值。
[ReliabilityContract(3, 2)]
public static long Add(ref long location1, long value);
//
// 摘要:
// 比较两个双精度浮点数是否相等,如果相等,则替换其中一个值。
//
// 参数:
// comparand:
// 与位于 location1 处的值进行比较的值。
//
// location1:
// 其值将与 comparand 进行比较并且可能被替换的目标。
//
// value:
// 比较结果相等时替换目标值的值。
//
// 返回结果:
// location1 中的原始值。
public static double CompareExchange(ref double location1, double value, double comparand);
//
// 摘要:
// 比较两个单精度浮点数是否相等,如果相等,则替换其中一个值。
//
// 参数:
// comparand:
// 与位于 location1 处的值进行比较的值。
//
// location1:
// 其值将与 comparand 进行比较并且可能被替换的目标。
//
// value:
// 比较结果相等时替换目标值的值。
//
// 返回结果:
// location1 中的原始值。
public static float CompareExchange(ref float location1, float value, float comparand);
//
// 摘要:
// 比较两个 32 位有符号整数是否相等,如果相等,则替换其中一个值。
//
// 参数:
// comparand:
// 与位于 location1 处的值进行比较的值。
//
// location1:
// 其值将与 comparand 进行比较并且可能被替换的目标。
//
// value:
// 比较结果相等时替换目标值的值。
//
// 返回结果:
// location1 中的原始值。
[ReliabilityContract(3, 2)]
public static int CompareExchange(ref int location1, int value, int comparand);
//
// 摘要:
// 比较两个平台特定的句柄或指针是否相等,如果相等,则替换其中一个。
//
// 参数:
// comparand:
// 与位于 location1 处的值进行比较的 System.IntPtr。
//
// location1:
// 其值与 comparand 的值进行比较并且可能被 value 替换的目标 System.IntPtr。
//
// value:
// 比较结果相等时替换目标值的 System.IntPtr。
//
// 返回结果:
// location1 中的原始值。
[ReliabilityContract(3, 2)]
public static IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand);
//
// 摘要:
// 比较两个 64 位有符号整数是否相等,如果相等,则替换其中一个值。
//
// 参数:
// comparand:
// 与位于 location1 处的值进行比较的值。
//
// location1:
// 其值将与 comparand 进行比较并且可能被替换的目标。
//
// value:
// 比较结果相等时替换目标值的值。
//
// 返回结果:
// location1 中的原始值。
public static long CompareExchange(ref long location1, long value, long comparand);
//
// 摘要:
// 比较两个对象是否相等,如果相等,则替换其中一个对象。
//
// 参数:
// comparand:
// 与位于 location1 处的对象进行比较的对象。
//
// location1:
// 其值与 comparand 进行比较并且可能被替换的目标对象。
//
// value:
// 在比较结果相等时替换目标对象的对象。
//
// 返回结果:
// location1 中的原始值。
[ReliabilityContract(3, 2)]
public static object CompareExchange(ref object location1, object value, object comparand);
[ComVisible(false)]
[ReliabilityContract(3, 2)]
public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class;
//
// 摘要:
// 以原子操作的形式递减指定变量的值并存储结果。
//
// 参数:
// location:
// 其值要递减的变量。
//
// 返回结果:
// 递减的值。
[ReliabilityContract(3, 2)]
public static int Decrement(ref int location);
//
// 摘要:
// 以原子操作的形式递减指定变量的值并存储结果。
//
// 参数:
// location:
// 其值要递减的变量。
//
// 返回结果:
// 递减的值。
public static long Decrement(ref long location);
//
// 摘要:
// 以原子操作的形式,将双精度浮点数设置为指定的值并返回原始值。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
public static double Exchange(ref double location1, double value);
//
// 摘要:
// 以原子操作的形式,将单精度浮点数设置为指定的值并返回原始值。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
public static float Exchange(ref float location1, float value);
//
// 摘要:
// 以原子操作的形式,将 32 位有符号整数设置为指定的值并返回原始值。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
[ReliabilityContract(3, 2)]
public static int Exchange(ref int location1, int value);
//
// 摘要:
// 以原子操作的形式,将平台特定的句柄或指针设置为指定的值并返回原始值。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
[ReliabilityContract(3, 2)]
public static IntPtr Exchange(ref IntPtr location1, IntPtr value);
//
// 摘要:
// 以原子操作的形式,将 64 位有符号整数设置为指定的值并返回原始值。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
public static long Exchange(ref long location1, long value);
//
// 摘要:
// 以原子操作的形式,将对象设置为指定的值并返回对原始对象的引用。
//
// 参数:
// location1:
// 要设置为指定值的变量。
//
// value:
// location1 参数被设置为的值。
//
// 返回结果:
// location1 的原始值。
[ReliabilityContract(3, 2)]
public static object Exchange(ref object location1, object value);
[ComVisible(false)]
[ReliabilityContract(3, 2)]
public static T Exchange<T>(ref T location1, T value) where T : class;
//
// 摘要:
// 以原子操作的形式递增指定变量的值并存储结果。
//
// 参数:
// location:
// 其值要递增的变量。
//
// 返回结果:
// 递增的值。
[ReliabilityContract(3, 2)]
public static int Increment(ref int location);
//
// 摘要:
// 以原子操作的形式递增指定变量的值并存储结果。
//
// 参数:
// location:
// 其值要递增的变量。
//
// 返回结果:
// 递增的值。
public static long Increment(ref long location);
//
// 摘要:
// 返回一个以原子操作形式加载的 64 位值。
//
// 参数:
// location:
// 要加载的 64 位值。
//
// 返回结果:
// 加载的值。
public static long Read(ref long location);
}
}
本文探讨了C#中的Interlocked类如何保证基本操作的原子性,避免多线程环境下的并发问题,通过具体接口实例展示了如何在多线程场景下使用Interlocked实现安全的数据操作。
1468

被折叠的 条评论
为什么被折叠?



