首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不同步Java集合的后果

不同步Java集合的后果
EN

Stack Overflow用户
提问于 2016-09-22 08:41:36
回答 3查看 169关注 0票数 1

我想知道不同步由多个线程在Java中修改的集合可能带来的最坏的后果(除了数据损坏)。

实际的例子是,线程数可以大于10,集合(HashSet)可以增长到大约10万个元素(甚至更多)。

谢谢

EN

回答 3

Stack Overflow用户

发布于 2016-09-22 09:24:50

由于HashSet在内部使用HashMap,所以您只需查看HashMap的putVal方法定义并亲自查看--在该方法执行的任何时候,另一个线程可能会开始执行相同的操作。例如,它可以将其调整为中等大小,这意味着数据可能被写入旧表,或者同时创建两个新表。

结果总是数据损坏,甚至可能在这类事件发生后失效。

票数 2
EN

Stack Overflow用户

发布于 2016-09-22 10:15:50

如果其中一个线程正在对集合进行迭代,而另一个线程正在修改它,则可以获得ConcurrentModificationException

详细说明见HashSet文档:

注意,此实现不是同步的。如果多个线程同时访问哈希集,并且至少有一个线程修改该集,则必须在外部同步它。这通常是通过对一些自然封装集合的对象进行同步来实现的。如果不存在这样的对象,则应该使用Collections.synchronizedSet方法“包装”集合。最好在创建时这样做,以防止意外地不同步地访问集合: Set s = Collections.synchronizedSet(new HashSet(...)); 这个类的迭代器方法返回的迭代器是快速失败的:如果在迭代器创建后的任何时候对集合进行了修改,那么除了通过迭代器自己的remove方法之外,其他任何方式都会抛出一个ConcurrentModificationException。因此,在并发修改的情况下,迭代器会迅速而干净地失败,而不是在未来某个未定的时间冒着任意的、不确定的行为的风险。 请注意,迭代器的快速失败行为不能保证,一般来说,在不同步并发修改的情况下不可能提供任何硬的保证。快速失败的迭代器在最大努力的基础上将ConcurrentModificationException抛出。因此,编写一个依赖于此异常的程序是错误的:迭代器的快速失败行为应该只用于检测bug。

票数 1
EN

Stack Overflow用户

发布于 2016-09-22 12:46:28

最糟糕的结果是,您的数据结构最终指向自身,例如,HashMap到Java 7可能会进入一个无限循环。这意味着您没有错误,而是您的线程永远不会返回。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39634192

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档