Let's say that I have a ConcurrentHashMap
of clients registered to a server (inside a class Server):
Map<ClientID, String> registeredClients = new ConcurrentHashMap<ClientID, String>();
In my registration method (inside the Server class) I have:
public void synchronized register(ClientID client, String clientName) {
if(!registeredClients.containsKey(client))
registeredClients.put(client, clientName);
}
And in any other methods of the server, I always check at the beginning that the client is registered (to be sure that he is eligible to use the method):
if(!registeredClients.containsKey(client))
throw new UnknownClientException();
I have one server thread per client.
Have I to synchronize that check with something like this?
synchronized(registeredClients) {
if(!registeredClients.containsKey(client))
throw new UnknownClientException();
}
I think I should because theoretically the client could register after having passed the if guard and before throwing the exception (making the exception actually wrong).
I am not quite how much the ConcurrentHashMap
helps programmers with synchronization issues.
If you are using Java 8, you can check with the following code:
The check if the key exists and the execution of the lambda are atomic. This requires UnknownClientException to be an unchecked exception.
For Java 7 I have no solution that is this simple.