Java ConcurrentHashMap 覆盖所有条目

Java ConcurrentHashMap overrides all entries

我正在开发一个多线程 client/server 应用程序,它通过套接字传输数据。我将 byte[] 片段存储在 ConcurrentHashMap<Integer, byte[]> 中,一切似乎都正常工作,直到最后一个 .put() 覆盖最后一个条目的所有条目。

   ...
   tf.putFragment(i, readBuffer.array());
   System.out.println("check added frag " + i + " : " + Arrays.toString(tf.getFragment(i)));

   }
barrier.await();
System.out.println("check added frag " + 5 + " : " + Arrays.toString(tf.getFragment(5)));
System.out.println("check added frag " + 10 + " : " + Arrays.toString(tf.getFragment(10)));

片段中的第一个 .put() 调用来自一个循环,在该循环中我添加了每个片段,然后检查它是否一切正常(确实如此)。之后我 select 3 个随机条目来检查它们,现在所有内容都被最后一次放置的数据覆盖,每个条目。

这可能是什么原因造成的?目前我只用 1 个线程进行测试。

输出:

downloaded frag 821 : [48, 48, 48, 53, 48, 55, 49, 49, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 53, 49, 52, 50, 55, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 53, 49, 54, 54, 54, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 50, 51, 56, 51, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 51, 48, 51, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 51, 50, 55, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 56, 53, 52, 49]
check added frag 821 : [48, 48, 48, 53, 48, 55, 49, 49, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 53, 49, 52, 50, 55, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 53, 49, 54, 54, 54, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 50, 51, 56, 51, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 51, 48, 51, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 55, 51, 50, 55, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 56, 53, 52, 49]
downloaded frag 822 : [32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 57, 49, 56, 50, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 57, 52, 50, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 48, 54, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 50, 56, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 55, 57, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 116, 114, 97, 105, 108, 101, 114, 10, 60, 60, 32, 47, 83, 105, 122, 101, 32, 53]
check added frag 822 : [32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 57, 49, 56, 50, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 48, 56, 57, 52, 50, 48, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 48, 54, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 50, 56, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 48, 48, 48, 48, 49, 48, 52, 48, 55, 57, 32, 48, 48, 48, 48, 48, 32, 110, 32, 10, 116, 114, 97, 105, 108, 101, 114, 10, 60, 60, 32, 47, 83, 105, 122, 101, 32, 53]
downloaded frag 823 : [54, 32, 47, 82, 111, 111, 116, 32, 51, 49, 32, 48, 32, 82, 32, 47, 73, 110, 102, 111, 32, 49, 32, 48, 32, 82, 32, 47, 73, 68, 32, 91, 32, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 10, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 32, 93, 32, 62, 62, 10, 115, 116, 97, 114, 116, 120, 114, 101, 102, 10, 49, 48, 52, 49, 57, 54, 10, 37, 37, 69]
check added frag 823 : [54, 32, 47, 82, 111, 111, 116, 32, 51, 49, 32, 48, 32, 82, 32, 47, 73, 110, 102, 111, 32, 49, 32, 48, 32, 82, 32, 47, 73, 68, 32, 91, 32, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 10, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 32, 93, 32, 62, 62, 10, 115, 116, 97, 114, 116, 120, 114, 101, 102, 10, 49, 48, 52, 49, 57, 54, 10, 37, 37, 69]
check added frag 5 : [54, 32, 47, 82, 111, 111, 116, 32, 51, 49, 32, 48, 32, 82, 32, 47, 73, 110, 102, 111, 32, 49, 32, 48, 32, 82, 32, 47, 73, 68, 32, 91, 32, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 10, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 32, 93, 32, 62, 62, 10, 115, 116, 97, 114, 116, 120, 114, 101, 102, 10, 49, 48, 52, 49, 57, 54, 10, 37, 37, 69]
check added frag 10 : [54, 32, 47, 82, 111, 111, 116, 32, 51, 49, 32, 48, 32, 82, 32, 47, 73, 110, 102, 111, 32, 49, 32, 48, 32, 82, 32, 47, 73, 68, 32, 91, 32, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 10, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 32, 93, 32, 62, 62, 10, 115, 116, 97, 114, 116, 120, 114, 101, 102, 10, 49, 48, 52, 49, 57, 54, 10, 37, 37, 69]
check added frag 15 : [54, 32, 47, 82, 111, 111, 116, 32, 51, 49, 32, 48, 32, 82, 32, 47, 73, 110, 102, 111, 32, 49, 32, 48, 32, 82, 32, 47, 73, 68, 32, 91, 32, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 10, 60, 56, 99, 97, 97, 55, 53, 52, 50, 55, 56, 101, 53, 48, 50, 97, 100, 49, 50, 102, 57, 57, 53, 50, 55, 54, 56, 56, 97, 50, 52, 57, 49, 62, 32, 93, 32, 62, 62, 10, 115, 116, 97, 114, 116, 120, 114, 101, 102, 10, 49, 48, 52, 49, 57, 54, 10, 37, 37, 69]

编辑: putFragment() 代码:

public void putFragment(int i,byte[] f) {
    fragments.put(i, f);
}

您似乎在使用 ByteBuffer 并将实际的字节数组放入映射的值中。

来自 ByteBuffer#array() javadoc :

Modifications to this buffer's content will cause the returned array's content to be modified, and vice versa.

因此,以后任何时候修改缓冲区,所有值也会更新。

您必须使用 java.util.Arrays.copyOf(byte[] src, int length)

复制缓冲区