c#线程同步的总结(摘抄)

.net中的线程同步方式非常之多。
常见的有如下几种
(1)lock关键字
lock的本质是monitor.enter,和monitor.exit。简单来讲进入大括号时执行的是monitor.enter(obj),离开大括号时执行的是monitor.exit(obj)。
lock不能锁定指向null的对象,不能锁定string类型虽然它也是引用。因为在.net中内容相同的字符串只有一个实例,如果加锁可能会引起其他地方的混乱。显然最好也不要锁定public的对象。
比较常见的用法是lock(this),相当于限制对象自身(不包括相同类的其他对象多次访问代码区域)。
其他的用法比如说lock(typeof(类的名称))。含义极为限制相同类所有对象的再次访问。

lock (x)
{
    DoSomething();
} 

等效于

object obj = ( object )x;
System.Threading.Monitor.Enter(obj);
try 
{
    DoSomething();
}
finally 
{
    System.Threading.Monitor.Exit(obj);
}

(2)使用monitor类
相比之下monitor类功能相对更多。比如bool gotLock = Monitor.TryEnter(myobject,1000)可以让线程自主决定。

(3)如果只需要避免缓存和主存不一致的情况,只需要使用volatile关键字好了,当多线程访问时,都将直接访问主存。

(4)使用system.threading.interlocked
这种方法可以对整形数据进行操作,保证对整形数据的操作为一个原子操作。

(5)mutex
相当于monitor的简化版本,不具备wait,pulse,pulseall等功能。不过mutex可以实现跨进程的,可以在不同进程甚至不同计算机上使用。尽管其可以实现线程同步,但是mutex来源于win32的封装,其转化需要消耗更多的系统资源。

(6)readerwriterlock
lock机制下,显然如果多个线程申请读数据也会发生资源独占。这种情况下可以使用readerwriterlock。如果有线程申请写数据,则该资源被锁定,否则多个读线程可以共享该区域。

(7)SynchronizationAttribute
当我们确定某个类的对象只能在同一时刻被同一线程访问时,可以在定义该类时为其加入属性并继承如下类

[System.Runtime.Remoting.Contexts.Synchronization]
public class SynchronizedClass : System.ContextBoundObject
{

} 

(8)MethodImplAttribute
和上述类似,在定义方法时,可以对一个方法添加该属性,规定其只被一个线程访问

[MethodImpl(MethodImplOptions.Synchronized)]
public void DoSomeWorkSync()
{
    Console.WriteLine( " DoSomeWorkSync() -- Lock held by Thread " + 
    Thread.CurrentThread.GetHashCode());
    Thread.Sleep( 1000 );
    Console.WriteLine( " DoSomeWorkSync() -- Lock released by Thread " + 
    Thread.CurrentThread.GetHashCode());
}

(9)同步事件和等待句柄
同步事件有两种,AutoResetEvent和 ManualResetEvent。这种用法本质上是传递事件。常用的方法有waitone和Set和Reset。前者在激活一个线程后自动变成reset状态,而后者可以激活任意多的线程直到手工调动reset。

你可能感兴趣的:(线程,.net)