您的位置:首页 > 编程语言 > C#

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

2016-04-11 16:01 344 查看
.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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: