c多线程同步methodimplmethodimploptionssynchronizedlockthis与locktypeofWord下载.docx
- 文档编号:20630211
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:7
- 大小:16.65KB
c多线程同步methodimplmethodimploptionssynchronizedlockthis与locktypeofWord下载.docx
《c多线程同步methodimplmethodimploptionssynchronizedlockthis与locktypeofWord下载.docx》由会员分享,可在线阅读,更多相关《c多线程同步methodimplmethodimploptionssynchronizedlockthis与locktypeofWord下载.docx(7页珍藏版)》请在冰豆网上搜索。
我们几天来讨论MethodImplAttribute(MethodImplOptions.Synchronized)和lock的关系。
一、提出结论
在进行讨论之前,我先提出下面3个结论:
1、[MethodImplAttribute(MethodImplOptions.Synchronized)]仍然采用加锁的机制实现线程的同步。
2、如果[MethodImplAttribute(MethodImplOptions.Synchronized)]被应用到instancemethod,相当于对当前实例加锁。
3、如果[MethodImplAttribute(MethodImplOptions.Synchronized)]被应用到staticmethod,相当于当前类型加锁
二、基于instancemethod的线程同步
为了验证我们上面提出的结论,我作了一个小小的例子。
在一个consoleapplication中定义了一个class:
SyncHelper,其中定义了一个方法Execute。
打印出方法执行的时间,并休眠当前线程模拟一个耗时的操作:
classSyncHelper
{
publicvoidExecute()
{
Console.WriteLine("
Excuteat{0}"
DateTime.Now);
Thread.Sleep(5000);
}
}
在入口Main方法中,创建SyncHelper对象,通过一个System.Threading.Timer对象实现每隔1s调用该对象的Execute方法:
classProgram
staticvoidMain(string[]args)
SyncHelperhelper=newSyncHelper();
Timertimer=newTimer(
delegate
helper.Execute();
},null,0,1000);
Console.Read();
由于Timer对象采用异步的方式进行调用,所以虽然Execute方法的执行时间是5s,但是该方法仍然是每隔1s被执行一次。
这一点从最终执行的结果可以看出:
为了让同一个SyncHelper对象的Execute方法同步执行,我们在Execute方法上添加了如下一个MethodImplAttribute:
[MethodImpl(MethodImplOptions.Synchronized)]
publicvoidExecute()
从如下的输出结果我们可以看出Execute方法是以同步的方式执行的,因为两次执行的间隔正式Execute方法执行的时间:
在一开始我们提出的结论中,我们提到&
#8220;
如果[MethodImplAttribute(MethodImplOptions.Synchronized)]被应用到instancemethod,相当于对当前实例加锁&
#8221;
。
说得直白一点:
[MethodImplAttribute(MethodImplOptions.Synchronized)]=lock(this)。
我们可以通过下面的实验验证这一点。
为此,在SyncHelper中定义了一个方法LockMyself。
在此方法中对自身加锁,并持续5s中,并答应加锁和解锁的时间。
publicvoidLockMyself()
lock(this)
Lockmyselfat{0}"
Unlockmyselfat{0}"
我们在Main()中以异步的方式(通过创建新的线程的方式)调用该方法:
staticvoidMain(string[]args)
Threadthread=newThread(
delegate()
{
helper.LockMyself();
});
thread.Start();
结合我们的第二个结论想想最终的输出会是如何。
由于LockMyself方法是在另一个线程中执行,我们可以简单讲该方法的执行和Execute的第一个次执行看作是同时的。
但是MethodImplAttribute(MethodImplOptions.Synchronized)]果真是通过lock(this)的方式实现的话,Execute必须在等待LockMyself方法执行结束将对自身的锁释放后才能得以执行。
也就是说LockMyself和第一次Execute方法的执行应该相差5s。
而输出的结果证实了这点:
三、基于staticmethod的线程同步
讨论完再instancemethod上添加MethodImplAttribute(MethodImplOptions.Synchronized)]的情况,我们相同的方式来讨论倘若一样的MethodImplAttribute被应用到static方法,又会使怎样的结果。
我们先将Execute方法上的MethodImplAttribute注释掉,并将其改为static方法:
//[MethodImpl(MethodImplOptions.Synchronized)]
publicstaticvoidExecute()
在Main方法中,通过Timer调用该static方法:
SyncHelper.Execute();
毫无疑问,Execute方法将以1s的间隔异步地执行,最终的输出结果如下:
然后我们将对[MethodImpl(MethodImplOptions.Synchronized)]的注释取消:
最终的输出结果证实了Execute将会按照我们期望的那样以同步的方式执行,执行的间隔正是方法执行的时间:
我们回顾一下第三个结论:
如果[MethodImplAttribute(MethodImplOptions.Synchronized)]被应用到staticmethod,相当于当前类型加锁&
为了验证这个结论,在SyncHelper中添加了一个新的static方法:
LockType。
该方法对SyncHelpertpye加锁,并持续5s中,在加锁和解锁是打印出当前时间:
publicstaticvoidLockType()
lock(typeof(SyncHelper))
LockSyncHelpertypeat{0}"
UnlockSyncHelpertypeat{0}"
在Main中,像验证instancemethod一样,创建新的线程执行LockType方法:
SyncHelper.LockType();
如果基于staticmethod的[MethodImplAttribute(MethodImplOptions.Synchronized)]是通过对Type进行加锁实现。
那么通过Timer轮询的第一个Execute方法需要在LockType方法执行完成将对SyncHelpertype的锁释放后才能执行。
所以如果上述的结论成立,将会有下面的输出:
四、总结
对于加锁来说,锁的粒度的选择显得至关重要。
在不同的场景中需要选择不同粒度的锁。
如果选择错误往往会对性能造成很到的影响,严重时还会引起死锁。
就拿[MethodImplAttribute(MethodImplOptions.Synchronized)]来说,如果开发人员对它的实现机制不了解,很有可能使它lock(this)或者lock(typeof(&
#8230;
))并存,造成方法得不到及时地执行。
最后说一句题外话,因为字符串驻留机制的存在,切忌对string进行加锁。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多线程 同步 methodimplmethodimploptionssynchronizedlockthis locktypeof
链接地址:https://www.bdocx.com/doc/20630211.html