[英]Synchronized in a Java thread
My program is a client connected to multiple servers. 我的程序是连接到多个服务器的客户端。 I save connection objects to all servers in a static map object: 我将连接对象保存到静态映射对象中的所有服务器:
server1 -> connection1 服务器1->连接1
server2 -> connection2 服务器2->连接2
serverN -> connectionN serverN-> connectionN
public class CacheConnection {
private final static Map cacheConnection = new HashMap();
public static void add(String serverName, Socket sock) {
synchronized (cacheConnection) {
cacheConnection.put(serverName, sock);
}
}
public static Socket get(String serverName) {
return (Socket) cacheConnection.get(serverName);
}
..
}
I have many threads getting connections from this map to communicate with the servers. 我有许多线程从此映射获取连接以与服务器通信。 How can I ensure a connection can only be used by one thread at a time? 如何确保一个连接一次只能由一个线程使用?
For example, I want to be sure thread 1 and thread 2 cannot use connection 1 at the same time. 例如,我想确保线程1和线程2不能同时使用连接1。
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 method that send or receive (eg, because you use a higher abstraction level like RMI): 如果您的连接具有多个发送或接收方法(例如,因为您使用的是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)));
}
Or, in your initial example, the get method could just remove the connection from the map. 或者,在您的第一个示例中,get方法可能只是从地图上删除了连接。 Of course, that means the client would have to be sure (probably in a finally
block, to call add again, when done) 当然,这意味着客户端必须确定(可能在finally
块中,完成后再次调用add)
Then have wait and notify loops for when a client comes in to ask for a connection, and it's not there. 然后,等待并通知循环,以了解何时有客户端进入以请求连接,但该连接不存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.