c#中集合类的线程安全问题

Acettest 2017-08-09 08:55:21
以下内容引用自MSDN:
Remarks
The wrapper returned by this method locks the queue before an operation is performed so that it is performed in a thread-safe manner.
To guarantee the thread safety of the Queue, all operations must be done through this wrapper only.
Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
Examples
The following code example shows how to lock the collection using the SyncRoot during the entire enumeration. This method is an O(1) operation.
Queue myCollection = new Queue();
lock(myCollection.SyncRoot)
{
foreach (object item in myCollection)
{
// Insert your code here.
}
}
这是不是说,即使使用了Queue.Synchronized Method (Queue)方法来包装一个集合类,也无法确保集合的线程安全?
...全文
534 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2017-08-09
  • 打赏
  • 举报
回复
引用 9 楼 u010178308 的回复:
请恕小生愚钝,从您的回答中我还是没理解到底要不要在遍历queue时,对一个已经使用了Synchronized方法的queue加lock。
上面这个是msdn的解释。说白了,就是让你加Lock。 但其实本来就有线程安全的集合,你为何不使用?
浪子-无悔 2017-08-09
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
咱还是少用这么复杂的玩意吧,别把自己玩死了 哈哈!!
xuzuning 2017-08-09
  • 打赏
  • 举报
回复
C# 对所有集合类都提供有线程安全的版本 如要在线程中操纵全局的传统集合类,应该加锁(lock)而不是图侥幸
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 1 楼 diaodiaop 的回复:
首先,十分感谢恩师为我解惑,同时,也很好奇,您此图是来源于哪本书的截图?可否告之以让小弟参考参考,谢谢
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
请恕小生愚钝,从您的回答中我还是没理解到底要不要在遍历queue时,对一个已经使用了Synchronized方法的queue加lock。
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 u010178308 的回复:] 那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
Queue没有下标访问方式,用不用for循环有何区别呢,你可以看作仅仅是把正常的代码写在for循环里而已,所以不影响其线程安全性[/quote]谢谢,刚刚那个问题问的让我很难堪,抱歉抱歉
正怒月神 2017-08-09
  • 打赏
  • 举报
回复
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
xdashewan 2017-08-09
  • 打赏
  • 举报
回复
引用 5 楼 u010178308 的回复:
那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
Queue没有下标访问方式,用不用for循环有何区别呢,你可以看作仅仅是把正常的代码写在for循环里而已,所以不影响其线程安全性
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 4 楼 xdashewan 的回复:
我的理解是这样的,首先Queue.Synchronized方法返回的那个Queue是线程安全的,备注中提到的是当你使用foreach这样的枚举器的时候是线程不安全的,需要lock
那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
xdashewan 2017-08-09
  • 打赏
  • 举报
回复
我的理解是这样的,首先Queue.Synchronized方法返回的那个Queue是线程安全的,备注中提到的是当你使用foreach这样的枚举器的时候是线程不安全的,需要lock
  • 打赏
  • 举报
回复
使用lock可以保证当前只能有一个线程对其操作。 上边说的意思是迭代集合不是线程安全的,如果不用lock,其它线程操作集合会引发异常。用lock 不会造成操作结果混乱。
by_封爱 版主 2017-08-09
  • 打赏
  • 举报
回复
我的理解就是 线程安全集合 只是内部实现了lock而已. 所以 lock+非线程安全集合 ==线程安全集合
by_封爱 版主 2017-08-09
  • 打赏
  • 举报
回复

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧