Mark一些关于线程同步的信息
详细参见:http://xxinside.blogbus.com/logs/46441956.html
http://www.cnblogs.com/LoveJenny/tag/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA/
1、Interlocked
提供原子操作,下列方法:Increment, Decrement, Add, CompareExchange, Exchange, MemoryBarrier
//CompareExchange:将target和startVal的值比较,相等则用desiredVal替换,否则不操作,
//不管替换还是不替换返回的都是原来保存在target的值。
Interlocked.CompareExchange(ref target, desiredVal, startVal);
MemoryBarrier参见
http://www.geniusleft.com/notes/post/e585b3e4ba8eSystemThreadingThreadMemoryBarrier().aspx
2、lock,对Monitor的封装
lock(x)
{
DoSomething();
}
等价于:
System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
DoSomething();
}
finally
{
System.Threading.Monitor.Exit(obj);
}
3、Monitor
基本方法:Enter, TryEnter 可以指定等待进入的超时时间, Exit
更高级的方法:Wait, Pulse, PulseAll。可以跟lock配合使用
4、Mutex
可以理解为提供AppDomain间的同步,当然Monitor/lock的对象继承自MarshalByRefObject,效果一样。更像lock,锁定对象即为自己。开销很大,如果不是AppDomain间同步
,不推荐。
基本方法:WaitOne, ReleaseMutex,等效于Monitor的Enter, Exit,而不是Wait, Pulse,因为WaitOne的时候并不会释放信号量。
很酷的应用方式,可以完全保证应用程序的单例。
5、WaitHandle
EventWaitHandle, AutoResetEvent, ManualResetEvent
基本方法:SingleAndWait, WaitAll, WaitAny, Set. SingleAndWait可以用来在主线程中同步子线程中的开始和完成。
AutoResetEvent是每次Set释放之后自动进入加锁状态(nonsignaled),ManualResetEvent是需要显式调用Reset才能进入加锁状态,否则这个信号量处于有信号状态
(signaled)。
可以用于管理扔进ThreadPool中的线程。构造函数中的bool值表明创建时是Signaled or nonSignaled
6、Semaphore
一个允许多个线程进入的“Mutex”,线程无关,Mutex是线程相关的。Semaphore,Mutex,WaitHandle都可以跨应用程序域