.NET CLR - 对象引用同步
在多线程 .NET 应用程序中,
假设第一个线程正在写入列表 第二个线程正在清除其中的所有项目。 第三个线程正在从列表中读取。
如果第二个和第三个线程在 CLR 级别上“真正”同时访问同一个列表对象,会发生什么情况。我的意思不是.NET 同步对象和锁定机制。
我的意思是,当 CLR 从引用(通过第三个线程)访问列表项时,如果引用指向的列表发生更改(通过第二个线程)会发生什么?
In a multhreaded .NET application,
Assume first thread is writing into a List
Second thread is clearing all the items in.
And third thread is reading from the list.
What happens if second and third threads access the same list object at "really" same time on CLR level. I am not meaning .NET synchronization objects and lock mechanism.
I mean, when CLR accesses to the list items from reference (by 3rd thread)), what happens if the list that is pointed by reference change (by 2nd thread)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
坏东西。
Bad stuff.
它爆炸了。由于枚举已更改,因此引发
InvalidOperationException
。It blows up.
InvalidOperationException
is thrown since the enumeration has changed.如果您倾向于更新列表并在多线程代码中读取它,那么可能会发生很多失败,例如,假设我们有以下场景:
写入线程正在更新列表同时读取器线程从列表中读取,因此假设执行如下:
读取器线程检查集合中是否有项目,并发现其中有一些项目“
.Count > 0
is true”,因此它继续,但在到达下一行之前,线程上下文切换通过切换到写入器线程来暂停读取器线程,因此它执行其代码myList.Clear();
,此时线程上下文切换回来到读取器线程继续执行,因此它尝试获取myList[0]
,但写入器线程此时集合为空,因此它将失败并出现异常IndexOutOfRange
。另一种情况是,如果读取器线程迭代使用
foreach
抛出集合,编写器线程只是更改集合“添加/删除”一些项目,它会再次抛出异常,因为循环时集合发生更改。所以你必须使用一些同步机械化与交互时列表,例如 C# 中的
lock
或使用Monitor
类。但是,如果您使用的是4.0
,您可以切换到使用ConcurrentCollection< /code> 它们不是普通的列表,而是线程安全的集合。
There is so many failures could occurs, if you tends to update the list and read it in multithreading code, for instance lets say we have the following scenario:
The writing thread is updating the list at the same time the reader thread is reading from the list, so suppose the execution was as the following:
The reader thread check if there is an items at the collection, and it find that there is some itms on it "
.Count > 0
is true" so it proceed, but before it reaches the next line, the thread context switching pause the reader thread by switching to the writer thread, so it execute the its codemyList.Clear();
at that point the thread context switches back to the reader thread to continue its execution, so it tries to getmyList[0]
, but the collection was empty at that point by the writer thread, so it will fail with exceptionIndexOutOfRange
..Another scenario that if the reader thread where iterating throw the collection using
foreach
, and the writer thread just changes the collection "added/removed" some items, it will throw exception again because of the collection changed while looping..So you have to use some synchronization mechanizem when interacting with the list such as
lock
in C# or usingMonitor
class.. However if you are using4.0
you can switch off to usingConcurrentCollection
instead of normal lists, they are thread safe collections.