ConcurrentHashMap:我们能相信吗?

从ConcurrentHashMap的文档:

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

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

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

 Map<Integer,ArrayList> 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 featureVector,ListweightVector) 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.0081088544712​​93185,-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.06649040730064464,-0.04940329664431305,-0.027481729446035053,-0.0571846057609884,-0.036738550618481455,-0.035608113682344365]

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

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

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

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

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

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

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

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

我建议你添加一些跟踪代码来看看是什么

  getScore(contextFeatureVector, entry.getValue()) 

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

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