java:在同步块的循环中记录proto对象

java:在同步块的循环中记录proto对象,java,synchronization,log4j,protocol-buffers,Java,Synchronization,Log4j,Protocol Buffers,我有一个映射,它在线程x和y中写入,在线程z中读取 线程x: synchronized (map) { map.put(0, protoObjX); // protoObjX is a protocol buffer object } //... synchronized (map) { map.remove(0); } 螺纹y: synchronized (map) { map.put(1, protoObjY); // protoObjY is a protocol

我有一个
映射
,它在线程x和y中写入,在线程z中读取

线程x:

synchronized (map) {
    map.put(0, protoObjX); // protoObjX is a protocol buffer object
}
//...
synchronized (map) {
    map.remove(0);
}
螺纹y:

synchronized (map) {
    map.put(1, protoObjY); // protoObjY is a protocol buffer object
}
//...
synchronized (map) {
    map.remove(1);
}
线程z:

synchronized (map) {
    logger.info(map.values().size()); // prints 2
    for (ProtoObjType obj: map.values()) {
        logger.info(obj); // logger is a org.apache.log4j.Logger
    }
}
仅打印protoObjX或protoObjY。决不能两者兼而有之。为什么会发生这种情况


如果我做了
logger.info(map.values())而不是一个一个,然后它工作。如果使用POJO而不是proto obj,那么它就可以工作。

没有理由因为protobuf而导致这种行为不当。我闻到了一种典型的比赛状态。试试这个,在一个线程中


如果它能工作,我100%确信它会工作,那么你需要弄清楚在工作和不工作的情况下线程计时的差异是什么。我怀疑当protobuf对象从某个网络层接收时,您在本地对POJO进行了测试。

我忘记添加两个元素都在那里的事实。这张地图的大小是两个。请参阅我编辑的问题。尝试使用
System.out.println
而不是log4j,并尝试从迭代的每个ProtobjType打印一些特定的字符串值,而不是依赖于未指定的toString强制。如果我得到字段肯定会起作用,但当使用强制toString时确实会发生一些奇怪的事情,所以你应该提出一个新问题“Java protobuf对象上的奇怪toString”,因为这与线程无关。你使用的映射的实现是什么?可能是马车。
map.put(0, protoObjX); // protoObjX is a protocol buffer object
map.put(1, protoObjY); // protoObjY is a protocol buffer object
for (ProtoObjType obj: map.values()) {
  logger.info(obj); // logger is a org.apache.log4j.Logger
}