说在最前面
在多线程中编程中,少不了需要对共享资源的同步。此时就需要对资源同步的相关知识,在C#中,提供了如下几种线程资源同步的方式。
将字段使用volatile关键字修饰
当一个字段被声明为volatile关键字时,CLR中一些管理代码和内存的内部机制将负责对字段进行同步,并且总能保证读取到的字段信息都为最新的值,。
声明为volatile的关键字必须具备如下:
- 引用类型
- (不安全代码的)指针
- sbyte,byte,short,ushort,int,uint,char,float,bool
- 一个使用底层类型的枚举类型。
class TestVolatile
{
public volatile int Number;
}
System.Threading.Interlocked 类
在多线程中对整数自增操作,我们都容易忽略其操作的原子性。如
int i = 0;
i += 1;
i += i 可以分为三步
- 从内存中读取i的值
- 将读取出来的值加一
- 新值写入内存
在多线程中上述任何一步操作都有可能被打断,从而导致实际的值并不是我们所需要的,此时就需要保证操作的原子性。
.NET框架提供Interlock类来提供原子性,其中有三个方法。
Increment //自增
Decrement //自减
Exchange //交换
int i = 0;
System.Threading.Interlocked.Increment(ref i);
Console.WriteLine(i); System.Threading.Interlocked.Decrement(ref i);
Console.WriteLine(i);
System.Threading.Interlocked.Exchange(ref i, 100);
Console.WriteLine(i);
lock关键字
lock关键字获得一个对象的侵占权,提供了简单资源的同步方式,.NET中不提倡lock(this)
简单使用
Object o = new Object
lock(0)
{
.....
}
System.Theading.Monitor类
该类提供了与lock关键字类似的功能,而与lock不同的是,能够更好的控制同步块,该类Enter(object o)方法调用后,会获取o的侵占权。直到调用Exit(object o)方法时才会释放。且Enter与Exit是配套的,并且还该类提供了TryEnter方法来尝试侵占
class Progr