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);
contextFeatureVector
和entry.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.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.06649040730064464,-0.04940329664431305,-0.027481729446035053,-0.0571846057609884,-0.036738550618481455,-0.035608113682344365]
因此,getScore返回的值不会特别大。 它将成千上万。
它是线程安全的,但可以使用非线程安全的方式。
我怀疑你没有充分调查这个问题,以确定JDK库中有一个已经使用了十多年的错误。
您使用的数据结构让我相信您的代码中必定存在一些错误。 您很可能是从地图中获取列表并更新它:
map1.get(42).add(5);
请注意, add(5)
不是线程安全的,因为它在普通的ArrayList
。 您需要线程安全的ArrayList
或replace(K key, V oldValue, V newValue)
方法。
如果仔细阅读ConcurrentHashMap
提供的保证,您可以有效地使用它。
如果在输入太大的情况下调用Math.exp(...)
,您将获得无限。 这可能是你的问题的原因…不是线程安全的一些想象的问题。
我建议你添加一些跟踪代码来看看是什么
getScore(contextFeatureVector, entry.getValue())
当sum
变为Infinity时返回。 除此之外,我认为如果不看到更多代码,我们将无法提供帮助。
可以存储在Java double
的最大数字大约是exp(709)
。 因此,如果将大于709的任何内容传递给exp()
,您应该会得到算术溢出。