C#用于线程同步的方法有lock statement,Interlocked class,Monitor class,wait handles(抽象基类,后续的Mutex,Semaphore,Event均为WaitHandle的实现子类),Mutex,Semaphore,Events,ReaderWriterLockSlim,其中lock statement, Interlocked class以及Monitor class可以用于同一进程的线程间同步,而Mutex,Semaphore,Events以及ReaderWriterLockSlim可以用于不同进程的线程间同步。
lock statement:
使用C#的关键字lock进行代码区域加锁:
lock (obj) //锁定引用对象实例,不能是值对象,用于对象实例级别的代码同步
{
//同步代码区域
或者
lock (typeof(class)) //锁定类对象,用于类级别的静态代码同步
//同步代码区域
Interlocked class:
Interlocked class是一种相对于其他同步方法更快的但只能用于变量修改同步的方法。
Interlocked class提供了以下静态方法用于同步变量的修改操作:
Increment,Decrement,Exchange,CompareExchange,Add,Read(用于在32系统从内存中原子的读取64比特值)
Monitor class:
Monitor class提供了一些静态方法用于实现线程同步,与lock statement相比可以指定加锁的超时时间。
//无超时
Monitor.Enter(obj);
//同步代码区域
finally
Monitor.Exit(obj);
//超时
if (Monitor.TryEnter(obj, 500))
try
{
//同步代码区域
}
finally
{
Monitor.Exit(obj);
}
else
//加锁超时
Wait handle:
WaitHandle是一个抽象基类,表示一个可以被signal的资源对象,定义了如下方法:
WaitOne 实例方法,用于等待资源对象被signal,可以指定超时时间
WaitAll 静态方法,等待waithandle数组中的所有资源对象被signal
WaitAny 静态方法,等待waithandle数组中的任一资源对象被signal,返回被signal的资源对象在数组中的索引,可以指定超时时间,如果超时则返回WaitTimeOut
Mutex:
Mutex每次只能有一个线程加锁成功,Mutex可以指定创建的时候是否加锁以及可以为Mutex指定一个名字,有名的Mutex可以用于不同进程间的线程互斥,而无名Mutex只能用于同一进程中的线程互斥,另外Mutex的构造函数还可以指定一个out参数用于接收构造的Mutex对象是创建了一个新的Mutex互斥体还是打开了一个已经存在的Mutex互斥体操作,除了使用new创建Mutex对象以外还可以调用Mutex.OpenExisting方法打开一个已经存在的互斥体。
Mutex继承自WaitHandle,因此可以调用WaitHandle定义的wait系列方法加锁,释放锁则调用Mutex.ReleaseMutex方法。
if (mutex.WaitOne())
{
try
{
// synchronized region
}
finally
{
mutex.ReleaseMutex();
}
}
else
{
// some problem happened while waiting
}
Semaphore:
跟Mutex的区别是semaphore是一个计数型Mutex,也就是一次可以有多个线程同时锁定Semaphore,Semaphore的计数代表有多个可供访问的资源,因此也就允许同时计数个线程加锁访问。
Event:
Event分为ManualResetEvent以及AutoResetEvent,ManualResetEvent当调用Set对Event进行Singal之后所有等待此Event被Singal的线程均从睡眠等待中返回,调用Reset将Event重置为未singal状态。而AutoResetEvent与ManualResetEvent不同的是当调用Set对Event进行Singal之后只有一个线程(优先级别最高的线程)能够从等待中返回并且返回之前将Event重置为未singal状态。
ReaderWriterLockSlim:
读写锁,多个读线程可以同时读锁定,读锁与写锁互斥,写锁之间也互斥,提供方法如下:
TryEnterReadLock, EnterReadLock, ExitReadLock 操作读锁
TryEnterUpgradableReadLock, EnterUpgradableReadLock, ExitUpgradableReadLock 操作可更新读锁(也就是在拥有读锁的时候可以不释放读锁升级为写锁)
TryEnterWriteLock, EnterWriteLock, ExitWriteLock 操作写锁
ReaderWriterLockSlim的构造函数能够指定读写锁是否为可递归锁,也就是同一线程能对同一读写锁进行多次加锁操作而不会死锁。
来源:https://www.cnblogs.com/czjone/archive/2010/12/04/1896495.html