b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

c# 多线程 syncroot_c++泛型死锁_object-c 线程(2)

电脑杂谈  发布时间:2019-10-02 07:02:33  来源:网络整理

当我们确认某个类的例子在同一时刻只能被一个线程访问时,我们可以直接将类标识成Synchronization的,这样,CLR会自动对这个类实行同步模式,实际上,这上面涉及到同步域的概念,当类按如下设计时,我们可以保证类的例子能够被多个线程同时访问

1).在类的声明中,添加System.Runtime.Remoting.Contexts.SynchronizationAttribute属性。

2). 继承至System.ContextBoundObject

需要切记的是,要推动上述措施,类需要继承至System.ContextBoundObject,换句话说,类需要是上下文绑定的。

一个示范类代码如下:

Code

[System.Runtime.Remoting.Contexts.Synchronization]

publicclassSynchronizedClass : System.ContextBoundObject

{

}


八、MethodImplAttribute

如果临界区是跨越整个方式的,也就是说,整个步骤内部的代码都应该上锁的话,使用MethodImplAttribute属性会更简洁一些。这样就不用在步骤内部加锁了,只应该在原则里面加上 [MethodImpl(MethodImplOptions.Synchronized)] 就可以了,MehthodImpl和MethodImplOptions都在命名空间System.Runtime.CompilerServices里面。但要切记这个属性会使整个步骤加锁,直到技巧返回,才释放锁。因此,使用上不太灵活。如果要提早释放锁,则需要使用Monitor或lock。我们来看一个例子:

复制代码

Code

[MethodImpl(MethodImplOptions.Synchronized)]

publicvoidDoSomeWorkSync()

{

Console.WriteLine("DoSomeWorkSync() -- Lock held by Thread"+

Thread.CurrentThread.GetHashCode());

Thread.Sleep(1000);

Console.WriteLine("DoSomeWorkSync() -- Lock released by Thread"+

Thread.CurrentThread.GetHashCode());

}

publicvoidDoSomeWorkNoSync()

{

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

Thread.CurrentThread.GetHashCode());

Thread.Sleep(1000);

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

Thread.CurrentThread.GetHashCode());

}

[STAThread]

staticvoidMain(string[] args)

{

c++线程死锁_object-c 线程_c# 多线程 syncroot

MethodImplAttr testObj=newMethodImplAttr();

Thread t1=newThread(newThreadStart(testObj.DoSomeWorkNoSync));

Thread t2=newThread(newThreadStart(testObj.DoSomeWorkNoSync));

t1.Start();

t2.Start();

Thread t3=newThread(newThreadStart(testObj.DoSomeWorkSync));

Thread t4=newThread(newThreadStart(testObj.DoSomeWorkSync));

t3.Start();

t4.Start();

Console.ReadLine();

}


复制代码

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

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

九、同步事件和期待句柄

用lock和Monitor可以较好地起到线程同步的作用c# 多线程 syncroot,但他们能够推动线程之间释放事件。如果要推动线程同步的同时,线程之间需要有交互,就要用到同步事件。同步事件是有两个状态(终止和非终止)的对象,它可以拿来激活和挂起线程。

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

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

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

复制代码

Code

staticAutoResetEvent autoEvent;

staticvoidDoWork()

{

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

autoEvent.WaitOne();

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

}

[STAThread]

staticvoidMain(string[] args)

{

autoEvent=newAutoResetEvent(false);

Console.WriteLine("main thread starting worker thread");

Thread t=newThread(newThreadStart(DoWork));

t.Start();

Console.WriteLine("main thrad sleeping for 1 second");

Thread.Sleep(1000);

Console.WriteLine("main thread signaling worker thread");

autoEvent.Set();

Console.ReadLine();

}


复制代码

我们先来看一下输出:

在主函数中,首先建立一个AutoResetEvent的例子,参数false表示初始状况为非终止,如果是true的话,初始状况则为解除。然后建立并开启一个子线程,在子线程中,通过读取AutoResetEvent的WaitOne方法,使子线程等待指定事件的出现。然后主线程等待一秒后,调用AutoResetEvent的Set方法,使状况由非终止变为终止,重新激活子线程。

参考:

1/MSDN((VS.80).aspx)

2/http://www.cnblogs.com/VincentWP/archive/2008/06/25/1229104.html


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-124836-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 音越
      音越

      再看你是什么反应

    • 杨洁
      杨洁

      到现在潮水般的旅日

    • 曹僖公
      曹僖公

      显然一个统一的中华民族必然比目前的分裂状态下的内耗更好

    热点图片
    拼命载入中...