我正在玩 WebSocketServlet (tomcat),我有一些关于在没有竞争条件问题的情况下正确执行它的问题。
我有一个实例变量(非线程安全),它将跟踪所有 websocket 连接
HashMap<String,MyServers> myNonThreadSafeVariable = HashMap<String,MyServers>
这就是 HashMap 将包含的内容(大致......)
private final class MyServers extends MessageInbound {
final Set<MyClients> clients = new CopyOnWriteArraySet<MyClients>();
private String serverName;
@Override
protected void onOpen(WsOutbound outbound) {}
@Override
protected void onClose(WsOutbound outbound) {}
@Override
protected void onText(WsOutbound outbound) {}
}
private final class Clients extends MessageInbound {
private int clientID;
@Override
protected void onOpen(WsOutbound outbound) {}
@Override
protected void onClose(WsOutbound outbound) {}
@Override
protected void onText(WsOutbound outbound) {}
}
所以现在.. 在我的 servlet 生命周期中,我正在循环通过myNonThreadSafeVariable,然后可能还会循环通过myNonThreadSafeVariable.clients,然后可能还会修改或添加客户端或服务器等...
例如,当服务器连接时,在他的 onOpen 中会有类似
myNonThreadSafeVariable.put(key,this);
或者当客户在他的 onOpen 中连接时(不要担心这个)
server = myNonThreadSafeVariable,get(key);
sever.clients.add(this);
或者有时当我必须 ping 所有服务器的所有客户端时:
for (Entry<String, MyServers> entry : myNonThreadSafeVariable.entrySet()) {
MyServers server = entry.getValue();
server.sendMessage("ping||");
for (MyClients member : entry.getValue().clients) {
client.sendMessage("")
}
}
因此,如果我正确理解 myNonThreadSafeVariable 是全局的,那么 myNonThreadSafeVariable.clients 等也会如此。
所以我的问题是在这种情况下避免竞争条件的好习惯是什么?
在访问 myNonThreadSafeVariable 和 myNonThreadSafeVariable.clients 时使用互斥锁并对其进行同步?还是我应该完全避免使用实例变量?但是如何?
谢谢 !