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(类的名称))。含义极为限制相同类所有对象的再次访问。
(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
当我们确定某个类的对象只能在同一时刻被同一线程访问时,可以在定义该类时为其加入属性并继承如下类
(8)MethodImplAttribute
和上述类似,在定义方法时,可以对一个方法添加该属性,规定其只被一个线程访问
(9)同步事件和等待句柄
同步事件有两种,AutoResetEvent和 ManualResetEvent。这种用法本质上是传递事件。常用的方法有waitone和Set和Reset。前者在激活一个线程后自动变成reset状态,而后者可以激活任意多的线程直到手工调动reset。
常见的有如下几种
(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。
相关文章推荐
- C# WinForm开发系列 - DataGridView
- 有关DateTime
- C# 集合委托查找子元素
- C#通用类型转换 Convert.ChangeType
- C# 应用正则表达式
- C# 操作配置文件
- C# 编程常见十大问题
- pat1002
- c# Webservice技术整理
- C#学习笔记-线程
- C#学习笔记-WinForm
- C#中怎么定义不定长数组
- C#委托事件
- pat1001
- C#程序集使用强名字(Strong Name)签名/强名称签名
- C#泛型浅谈(浅~)自定义类型数组的排序
- C#控件及常用设计整理
- c# datagridview表格控件常用操作
- 使用反射和codeDom实现C#插件开发(4)主程序开发之main函数编写
- C# dateTime类型之subTract用法