putIfAbsent()不能与ConcurrentHashMap一起使用

Fix*_*xee 0 java concurrency hashmap concurrenthashmap

public static void main(String args[]) throws Exception {
    ConcurrentHashMap<byte[], Integer> dps =
         new ConcurrentHashMap<byte[], Integer>();

    System.out.println(dps.putIfAbsent("hi".getBytes(), 1));
    System.out.println(dps.putIfAbsent("hi".getBytes(), 1));
}
Run Code Online (Sandbox Code Playgroud)

版画

null
null
Run Code Online (Sandbox Code Playgroud)

为什么不在1第二行打印?我已经阅读了语义putIfAbsent,它应该保证工作.(注意:这是从大型并发程序中提炼出来的......正如您所看到的,它现在是单线程的.)

Gra*_*ray 5

putIfAbsent()不能与ConcurrentHashMap一起使用

"hi".getBytes()不是一个常量数组,所以你在那里生成两个不同的对象.如果你做了类似下面的事情,你会看到你的1.

byte[] bytes = "hi".getBytes();
System.out.println(dps.putIfAbsent(bytes, 1));
System.out.println(dps.putIfAbsent(bytes, 1));
Run Code Online (Sandbox Code Playgroud)

数组上的hashCode()equals(...)方法只能查看对象的引用,而不是它的内容.byte[]Object

每当你在某个东西中存储东西时,Map你需要确保它覆盖hashCode()equals(...)方法,除非你只想比较引用.这是一个Java FAQ.请参阅以下文档:Java理论与实践:将其排除在外.

作为@Mauren在评论中提到,要使用内容byte[],你将不得不写一个小类包装了byte[],并提供适当hashCode()equals(...)方法.或者@CostiCiudatu提到,您可以使用a SortedMap并使用a Comparatorbyte[]查看数组的内容.

顺便说String.getBytes()一句,如果返回一个基于你的字符集等new byte[]编码的StringCoding.StringEncoder类.

  • 或者你可以使用`SortedMap`(例如``TreeMap`)和`Comparator`来表示字节数组.这种方法在HBase中使用,只要为每个字节数组创建包装器对象太昂贵,它就适用. (2认同)