遍历红宝石哈希时同时修改

时间:2009-11-05 23:59:07

标签: ruby collections hash concurrency

假设你有这个:

def wipeProduct(hash, nameToDelete) 
  hash.each do |i| 
    key = i[0]
    productName = i[1].first
    hash.delete(key) if productName==nameToDelete
  end
end

我不确定在迭代哈希的键值对时从哈希中删除东西是安全的。我检查了RI文档,但我还没有看到关于Hash的并发修改的任何内容。

我知道你可以改写这个

def wipeProduct(hash, nameToDelete) 
  keysToDelete = []
  hash.each do |i| 
    key = i[0]
    productName = i[1].first
    keysToDelete << key if productName==nameToDelete
  end
  keysToDelete.each {|key| hash.delete(key) }
end

甚至:

def wipeProduct(hash, nameToDelete)
  hash.reject!{|key,value| nameToDelete==value.first}
end

但我想知道上面第一个例子中显示的并发修改是否有问题? (它似乎不是我运行代码时)

问题:有没有人知道并发修改的立场是什么? (......和其他收藏品?) - 如果你愿意的话,我当然喜欢任何记录此资源的链接。

1 个答案:

答案 0 :(得分:1)

只要没有其他线程试图访问哈希,任何这些方法都可以。如果有任何其他线程可以访问此哈希,则这些方法都不是显式线程安全的。你需要让它们保持安全,只需确保你的方法在哈希修改过程中获得一个锁定,事情就会好起来。

就个人而言,我会选择破坏性的reject_if!这是更清晰的代码,并且在不重现现有代码的情况下完成同样的事情。

相关问题