I use a ConcurrentHashMap to buffer messages for a websocket.
Every 200ms the buffer is sent in one JSON String. afterwards I want to remove the entry from the Map.
This is not safe I guess, because during the foreach there might come new messages to the buffer.
String sendString;
for(String msg : buffer.values()){
sendString += msg;
}
ws.send(sendString);
buffer.clear();
How could I safely remove the Elements?
Map#remove()
returns value that exists in map prior to removal. In ConcurrentHashMap
this is performed atomically, so you can safely consume the result:
StringBuilder sendString = new StringBuilder();
for (String key : buffer.keySet()) {
String s = buffer.remove(key);
if (s != null)
sendString.append(s);
}
You need to check the key and value.
StringBuilder sendString = new StringBuilder();
for (Map.Entry<String, String> entry : buffer.entrySet()) {
sendString.append(entry.getValue());
buffer.remove(entry.getKey(), entry.getValue()); // only remove a matching value
}
Use iterator explicitly:
StringBuilder result = new StringBuilder();
for (Iterator<String> it = buffer.values().iterator(); it.hasNext(); ) {
result.append(it.next());
it.remove();
}
Put your entire method block in a synchronized block. No other thread can write to the map while this code is being executed.
synchronized(buffer){
String sendString;
for(String msg : buffer.values()){
sendString += msg;
}
ws.send(sendString);
buffer.clear();
}
synchronized(buffer){
buffer.put(key, msg);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.