Multithreading Websocket Servlet线程安全

Multithreading Websocket Servlet线程安全,multithreading,servlets,thread-safety,websocket,Multithreading,Servlets,Thread Safety,Websocket,我正在玩WebSocketServlet(tomcat),我对如何在没有竞争条件问题的情况下正确地执行它有些疑问 我有一个实例变量(非线程安全),它将跟踪所有websocket连接 HashMap<String,MyServers> myNonThreadSafeVariable = HashMap<String,MyServers> 或者当一个客户在他的onOpen中连接时(不要担心这个) 有时,当我必须ping所有服务器的所有客户端时: for (Entry<

我正在玩WebSocketServlet(tomcat),我对如何在没有竞争条件问题的情况下正确地执行它有些疑问

我有一个实例变量(非线程安全),它将跟踪所有websocket连接

HashMap<String,MyServers> myNonThreadSafeVariable = HashMap<String,MyServers>
或者当一个客户在他的onOpen中连接时(不要担心这个)

有时,当我必须ping所有服务器的所有客户端时:

for (Entry<String, MyServers> entry : myNonThreadSafeVariable.entrySet()) {

   MyServers server = entry.getValue();
   server.sendMessage("ping||");

   for (MyClients member : entry.getValue().clients) {
      client.sendMessage("")
   }
}
for(条目:myNonThreadSafeVariable.entrySet()){
MyServers server=entry.getValue();
sendMessage(“ping | |”);
for(MyClients成员:entry.getValue().clients){
client.sendMessage(“”)
}
}
因此,如果我正确理解myNonThreadSafeVariable是全局变量,那么myNonThreadSafeVariable.clients等也将是全局变量

所以我的问题是,在这种情况下,什么是避免种族状况的好做法

在访问myNonThreadSafeVariable和myNonThreadSafeVariable.clients时使用互斥和同步?或者我应该避免使用实例变量吗?但是怎么做呢

谢谢

您可以使用:您在写入时阻止读卡器和写入器,在读取时仅阻止写入器:

private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
...
writeLock.lock();
try
{
    myNonThreadSafeVariable.put(key,this);
}
finally
{
    writeLock.unlock();
}
...
writeLock.lock();
try
{
    server = myNonThreadSafeVariable,get(key);
    sever.clients.add(this);
}
finally
{
    writeLock.unlock();
}
...
readLock.lock();
try
{
    for (Entry<String, MyServers> entry : myNonThreadSafeVariable.entrySet())
    {
        MyServers server = entry.getValue();
        server.sendMessage("ping||");

        for (MyClients member : entry.getValue().clients)
        {
            client.sendMessage("")
        }
    }
}
finally
{
    readLock.unlock();
}
private final ReadWriteLock lock=new ReentrantReadWriteLock();
私有最终锁readLock=Lock.readLock();
private final Lock writeLock=Lock.writeLock();
...
writeLock.lock();
尝试
{
myNonThreadSafeVariable.put(键,this);
}
最后
{
writeLock.unlock();
}
...
writeLock.lock();
尝试
{
server=myNonThreadSafeVariable,get(key);
服务器。客户端。添加(此);
}
最后
{
writeLock.unlock();
}
...
readLock.lock();
尝试
{
for(条目:myNonThreadSafeVariable.entrySet())
{
MyServers server=entry.getValue();
sendMessage(“ping | |”);
for(MyClients成员:entry.getValue().clients)
{
client.sendMessage(“”)
}
}
}
最后
{
readLock.unlock();
}
此外,如果您想避免读取锁定,您可以复制整个集合并扫描副本,以便在通知时更改原始集合的可能性

server = myNonThreadSafeVariable,get(key);
sever.clients.add(this);
for (Entry<String, MyServers> entry : myNonThreadSafeVariable.entrySet()) {

   MyServers server = entry.getValue();
   server.sendMessage("ping||");

   for (MyClients member : entry.getValue().clients) {
      client.sendMessage("")
   }
}
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
...
writeLock.lock();
try
{
    myNonThreadSafeVariable.put(key,this);
}
finally
{
    writeLock.unlock();
}
...
writeLock.lock();
try
{
    server = myNonThreadSafeVariable,get(key);
    sever.clients.add(this);
}
finally
{
    writeLock.unlock();
}
...
readLock.lock();
try
{
    for (Entry<String, MyServers> entry : myNonThreadSafeVariable.entrySet())
    {
        MyServers server = entry.getValue();
        server.sendMessage("ping||");

        for (MyClients member : entry.getValue().clients)
        {
            client.sendMessage("")
        }
    }
}
finally
{
    readLock.unlock();
}