Multithreading Websocket Servlet线程安全
我正在玩WebSocketServlet(tomcat),我对如何在没有竞争条件问题的情况下正确地执行它有些疑问 我有一个实例变量(非线程安全),它将跟踪所有websocket连接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<
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();
}