I’m writing some client-server-application where I have to deal with multiple threads. I’ve got some servers, that send alive-packets every few seconds. Those servers are maintained in a ConcurrentHashMap, that contains their EndPoints paired with the time the last alive-package arrived of the respective server.
Now I’ve got a thread, that has to “sort out” all the servers that haven’t sent alive-packets for a specific amount of time.
I guess I can’t just do it like that, can I?
for( IPEndPoint server : this.fileservers.keySet() )
{
Long time = this.fileservers.get( server );
//If server's time is updated here, I got a problem
if( time > fileserverTimeout )
this.fileservers.remove( server );
}
Is there a way I can get around that without aquiring a lock for the whole loop (that I then have to respect in the other threads as well)?
There is probably no problem here, depending on what exactly you store in the map. Your code looks a little weird to me, since you seem to save “the duration for which the server hasn’t been active”.
My first idea for recording that data was to store “the latest timestamp at which the server has been active”. Then your code would look like this:
If you really want to avoid that no code ever calls
markActiveduring a call toremoveInactive, there is no way around explicit locking. What you probably want is:markActiveare allowed.markActiveno calls toremoveInactiveare allowed.removeInactiveno calls tomarkActiveare allowed.This looks like a typical scenario for a
ReadWriteLock, wheremarkActiveis the “reading” operation andremoveInactiveis the “writing” Operation.