I am not completely sure, what you want. I assume that you want to guarantee that only one thread at a time accesses one particular server.
If your connection is something like a socket, then you can use it as a lock in a synchronization statement:
private void send(Connection c, Data d) {
synchronized (c) {
// for each connection object, only one thread may be inside this block.
// all other threads wait until the thread currently in this block exits it.
c.send(d);
}
}
// somewhere else ...
Data data = determineDataToSend()
Connection connection = map.get(key);
send(connection, data)
You can put the logic also into a decorator for the connection. This is especially useful if your connection has more than one mehtod that send or receive (e.g., because you use a higher abstraction level like RMI):
public interface PowerfulConnection {
public void doA();
public int doB(ParameterForB param);
}
public class ConnectionImpl implements PowerfulConnection {
// handles the actual connection
}
/**
* This method is a decorator for PowerfulConnection that synchronizes all method accesses.
*/
public class SynchronizedConnection implements PowerfulConnection {
private PowerfulConnection target;
public SynchronizedConnection(PowerfulConnection target) {
if (target == null) throw new NullPointerException();
this.target = target;
}
public synchronized void doA() {
target.doA();
}
public synchronized int doB(ParameterForB param) {
return target.doB(param);
}
}
If you are using the decorator approach, then the only thing you need to change is the instance creation. Instead of:
private void connect(key, connectionParams) {
map.put(key, new ConnectionImpl(connectionParams));
}
use
private void connect(key, connectionParams) {
map.put(key, new SynchronizedConnection(new ConnectionImpl(connectionParams)));
}