ConcurrentHashMap:我们能相信吗?

时间:2012-07-22 11:37:25

标签: java multithreading arraylist

来自ConcurrentHashMap的文档:

  

一个哈希表,支持检索的完全并发和可更新的预期并发性。

我们能完全相信ConcurrentHashMap是否可以进行线程安全操作?

我使用ConcurrentHashMap映射键及其值。我的键值对是:

Map<Integer,ArrayList<Double>> map1 = new ConcurrentHashMap();

键的大小范围为[0,1000000]。我有20个线程,可以一次访问/修改与一个键对应的值。这不是那么频繁,但这种情况是可能的。我是 通过以下方法获得无穷大:

Double sum =0.0; 
sum = sum + Math.exp(getScore(contextFeatureVector,entry.getValue())+constant);

contextFeatureVectorentry.getValue()是与密钥关联的arraylist。

[编辑]

 constant =0.0001

private double getScore(List<Double> featureVector,List<Double>weightVector) throws NullPointerException    
{
    double score =0.0;
    int length = featureVector.size();
    for (int i =0 ; i< length ; i++){
    score = score + (featureVector.get(i)*weightVector.get(i)); 
    }

    return score;
}

featureVector<> and weightVector looks like

weightVector


因此,getScore返回的值不会特别大。它会在 成千上万。

4 个答案:

答案 0 :(得分:3)

它是线程安全的,但可以使用非线程安全的方式。

我怀疑你没有充分调查这个问题,以确定JDK库中存在一个已经使用了十多年的错误。

答案 1 :(得分:3)

您使用的数据结构让我相信您的代码中必定存在一些错误。您很可能是从地图中获取列表并更新它:

map1.get(42).add(5);

请注意,add(5) 是线程安全的,因为它在普通ArrayList上运行。您需要线程安全的ArrayListreplace(K key, V oldValue, V newValue)方法。

如果您仔细阅读ConcurrentHashMap提供的保证,您可以有效地使用它。

答案 2 :(得分:2)

如果您在输入太大的情况下拨打Math.exp(...),您将获得无限。这可能是你的问题的原因......而不是线程安全的一些想象问题。

我建议您添加一些跟踪代码以查看

 getScore(contextFeatureVector, entry.getValue())
sum变为无限时,

返回。除此之外,如果没有看到更多代码,我认为我们无法提供帮助。

答案 3 :(得分:1)

可以存储在Java double中的最大数字大约是exp(709)。因此,如果将大于709的任何内容传递给exp(),则应该会出现算术溢出。