0

来自 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);

contextFeatureVector并且 entry.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

[-0.005554038592516575, 0.0048966974158881175, -0.05315976588195846, -0.030837804373964654, 0.014483064988148562, -0.018962129117649, -0.015221386014208877, 0.015825702365331477, -0.11363620479662287, 0.00802609847263844, -0.062106636476812194, 0.008108854471293185, -0.03193255218671684, 0.04949650992670292, -0.0545583154094599, -0.04873314092706468, 0.013534731656877033, 0.08433117163682455, 0.050310355477044114, -0.002420513353516017, -0.02708299928442614, -0.023489187394176294, -0.1277699782685597, -0.10071004855129333, 0.08649040730064464, -0.04940329664431305, -0.027481729446035053, -0.0571846057609884, -0.036738550618481455, -0.035608113682344365]

因此从 getScore 返回的值不会特别大。会有几千人。

4

4 回答 4

3

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

我怀疑您没有对问题进行足够的调查,无法确定 JDK 库中存在已使用十多年的错误。

于 2012-07-22T11:44:57.890 回答
3

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

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

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

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

于 2012-07-22T11:46:54.447 回答
2

如果你调用Math.exp(...)一个太大的输入,你会得到一个 Infinity。这可能是您的问题的原因......不是线程安全的一些想象问题。

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

 getScore(contextFeatureVector, entry.getValue())

sum成为 Infinity时正在返回。除此之外,我认为如果不看到您的更多代码,我们将无法提供帮助。

于 2012-07-22T11:52:31.970 回答
1

Java 中可以存储的最大数double约为exp(709). 因此,如果您将任何大于 709 的值传递给exp(),您应该期望得到算术溢出。

于 2012-07-22T12:10:53.637 回答