归纳一下C#线程同步的几种方法

2026/4/26 22:20:54

1). 在类的声明中,添加

System.Runtime.Remoting.Contexts.SynchronizationAttribute属性。 2). 继承至System.ContextBoundObject 需要注意的是,要实现上述机制,类必须继承至

System.ContextBoundObject,换句话说,类必须是上下文绑定的。 一个示范类代码如下:

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

八、MethodImplAttribute

如果临界区是跨越整个方法的,也就是说,整个方法内部的代码都需要上锁的话,使用MethodImplAttribute属性会更简单一些。这样就不用在方法内部加锁了,只需要在方法上面加上

[MethodImpl(MethodImplOptions.Synchronized)] 就可以了,MehthodImpl和MethodImplOptions都在命名空间

System.Runtime.CompilerServices 里面。但要注意这个属性会使整个方法加锁,

直到方法返回,才释放锁。因此,使用上不太灵活。如果要提前释放锁,则应该使用Monitor或lock。我们来看一个例子:

Code [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()); }

public void DoSomeWorkNoSync() {

Console.WriteLine( \ DoSomeWorkNoSync() -- Entered Thread is \ +

Thread.CurrentThread.GetHashCode()); Thread.Sleep( 1000 );

Console.WriteLine( \ DoSomeWorkNoSync() -- Leaving Thread is \ +

Thread.CurrentThread.GetHashCode()); }

[STAThread]

static void Main( string [] args) {

MethodImplAttr testObj = new MethodImplAttr();

Thread t1 = new Thread( new ThreadStart(testObj.DoSomeWorkNoSync));

Thread t2 = new Thread( new ThreadStart(testObj.DoSomeWorkNoSync)); t1.Start(); t2.Start();

Thread t3 = new Thread( new ThreadStart(testObj.DoSomeWorkSync));

Thread t4 = new Thread( new ThreadStart(testObj.DoSomeWorkSync)); t3.Start(); t4.Start();

Console.ReadLine(); }

这里,我们有两个方法,我们可以对比一下,一个是加了属性MethodImpl的DoSomeWorkSync(),一个是没加的DoSomeWorkNoSync()。在方法中Sleep(1000)是为了在第一个线程还在方法中时,第二个线程能够有足够的时间进来。对每个方法分别起了两个线程,我们先来看一下结果:

可以看出,对于线程1和2,也就是调用没有加属性的方法的线程,当线程2进入方法后,还没有离开,线程1有进来了,这就是说,方法没有同步。我们再来看看线程3和4,当线程3进来后,方法被锁,直到线程3释放了锁以后,线程4才进来。

九、同步事件和等待句柄

用lock和Monitor可以很好地起到线程同步的作用,但它们无法实现线程之间传递事件。如果要实现线程同步的同时,线程之间还要有交互,就要用到同步事件。同步事件是有两个状态(终止和非终止)的对象,它可以用来激活和挂起线程。

同步事件有两种:AutoResetEvent和 ManualResetEvent。它们之间唯一不同的地方就是在激活线程之后,状态是否自动由终止变为非终止。AutoResetEvent自动变为非终止,就是说一个AutoResetEvent只能激活一个线程。而ManualResetEvent要等到它的Reset方法被调用,状态才变为非终止,在这之前,ManualResetEvent可以激活任意多个线程。

可以调用WaitOne、WaitAny或WaitAll来使线程等待事件。它们之间的区别可以查看MSDN。当调用事件的 Set方法时,事件将变为终止状态,等待的线程被唤醒。

来看一个例子,这个例子是MSDN上的。因为事件只用于一个线程的激活,所以使用 AutoResetEvent 或 ManualResetEvent 类都可以。

Code

static AutoResetEvent autoEvent;

static void DoWork() {

Console.WriteLine(\worker thread started, now waiting on event\);

autoEvent.WaitOne();

Console.WriteLine(\worker thread reactivated, now exiting\); }

[STAThread]

static void Main(string[] args) {

autoEvent = new AutoResetEvent(false);

Console.WriteLine(\starting worker thread\); Thread t = new Thread(new ThreadStart(DoWork)); t.Start();

Console.WriteLine(\for 1 second\); Thread.Sleep(1000);

Console.WriteLine(\\); autoEvent.Set();

Console.ReadLine(); }


归纳一下C#线程同步的几种方法.doc 将本文的Word文档下载到电脑
搜索更多关于: 归纳一下C#线程同步的几种方法 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219