2017-02-03 1 views
0

Ich habe eine Map, die in Threads x und y geschrieben wird, und lesen Sie in Thread z.java: protokollieren Proto-Objekte in Schleife im synchronisierten Block

Gewinde x:

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

Gewinde y:

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

Gewinde 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 
    } 
} 

Nur protoObjX oder protoObjY wird gedruckt. Niemals beides. Warum passiert das?

Wenn ich logger.info(map.values()); statt für jeweils eine tun, dann funktioniert es. Wenn ein POJO anstelle von Proto obj verwendet wird, funktioniert es.

+0

Welche Implementierung einer Karte verwenden Sie? Es kann fehlerhaft sein. –

Antwort

0

Es gibt einfach keinen Grund, warum dies wegen Protobuf falsch sein sollte. Ich rieche eine klassische Race Condition. Versuchen Sie dies, in einem einzigen Thread.

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 
} 

Wenn es funktioniert, was ich bin 100% sicher, es wird, müssen Sie herausfinden, was die Zeitdifferenz zwischen dem Fall Faden ist, der und der man arbeitet, die nicht der Fall ist. Ich vermute, dass Sie POJOs lokal an Ort und Stelle testen, während die Protobuf-Objekte von einer Netzwerkschicht empfangen werden.

+0

Ich habe vergessen, die Tatsache hinzuzufügen, dass beide Elemente vorhanden sind. Die Größe der Karte ist zwei. Siehe meine bearbeitete Frage. – lf215

+0

Versuchen Sie es mit 'System.out.println' anstelle von log4j und versuchen Sie auch, einen bestimmten String-Wert aus jedem iterierten ProtoObjType zu drucken, anstatt von der nicht angegebenen toString-Zwangsbedingung abhängig zu sein. –

+0

Funktioniert definitiv, wenn ich Felder erhalte, aber tatsächlich passiert etwas komisches, wenn man den erzwungenen Tostring verwendet. – lf215

Verwandte Themen