首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在同步集合中安全使用迭代器

在同步集合中安全使用迭代器
EN

Stack Overflow用户
提问于 2014-05-27 15:41:46
回答 1查看 42关注 0票数 0

在关于synchronizedMap的教程中,我遇到了以下代码(来自教程的注释):

代码语言:javascript
复制
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet();  // Needn't be in synchronized block
...
synchronized(m) {  // Synchronizing on m, not s!
    Iterator i = s.iterator(); // Must be in synchronized block
    while (i.hasNext())
          foo(i.next());
}

我在源代码中看到,迭代器方法不是由同步节包装的。没问题的。

我害怕得到意想不到的东西

代码语言:javascript
复制
Set s = m.keySet();  
// Could happen something unexpected here ?
synchronized(m) { 

请澄清为什么这段代码是安全的?

代码语言:javascript
复制
 synchronized(m) {  // Synchronizing on m, not s!
        Set s = m.keySet();  // Needn't be in synchronized block
        Iterator i = s.iterator(); // Must be in synchronized block
        while (i.hasNext())
              foo(i.next());
    }

这种同步是否过度了?

EN

回答 1

Stack Overflow用户

发布于 2014-05-27 15:52:52

虽然Collections.synchronizedMap()保证包装的map上的每个操作都是线程安全的,但它并不保证在其上迭代是线程安全的。当您在迭代的同时在map上同步时,您就保证了当一个线程在map上迭代时,另一个线程不能访问它(毕竟,您希望确保您以原子的方式迭代它)。

如果没有这种同步,另一个线程可能会在i.hasNext() while循环之间执行一个或多个操作。

其实现是synchronizedMap()包装器在集合本身上同步(在您的代码m中),因此使用synchronized(m)获取对象监视器可以确保在完成迭代之前,另一个线程无法访问它。

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

https://stackoverflow.com/questions/23883684

复制
相关文章

相似问题

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