我之前使用过 HashMap
public Map<SocketChannel, UserProfile> clients = new HashMap<SocketChannel, UserProfile>();
现在我已经切换到 ConcurrentHashMap 以避免同步块,现在我遇到了问题,我的服务器每秒负载 200-400 个并发客户端,预计会随着时间的推移而增长。
现在看起来像这样
public ConcurrentHashMap<SocketChannel, UserProfile> clients = new ConcurrentHashMap<SocketChannel, UserProfile>();
我的服务器设计是这样的。
我有一个工作线程用于处理大量数据包。每个数据包都使用 packetHandler 子例程(不是线程的一部分)进行检查,几乎任何客户端都可以随时调用它,它几乎就像静态的,但事实并非如此。
除了数据包处理部分之外,我的整个服务器大部分都是单线程的。
无论如何,当有人使用诸如统计所有在线客户端之类的命令并从他们那里获取一些信息时。
客户端也有可能断开连接并从其中删除并发哈希映射当计数正在进行时(这导致了我的问题)。
我还想在这里添加一些代码。
int txtGirls=0;
int vidGirls=0;
int txtBoys=0;
int vidBoys=0;
Iterator i = clients.values().iterator();
while (i.hasNext()) {
UserProfile person = (UserProfile)i.next();
if(person != null) {
if(person.getChatType()) {
if(person.getGender().equals("m"))
vidBoys++;
else //<-- crash occurs here.
vidGirls++;
} else if(!person.getChatType()) {
if(person.getGender().equals("m"))
txtBoys++;
else
txtGirls++;
}
}
}
我的意思是,我当然会通过在迭代器内添加一个 try-catch 异常来跳过这些空客户端来修复它。
但我不明白的是,如果它检查上面的 if(person != null) ,嵌套的代码是否应该自动工作。
如果这并不意味着它在迭代时被删除,那么这应该是不可能的,因为它是线程安全的wtf?
我应该怎么办?还是 try-catch Exception 是最好的方法?
这是例外情况
java.lang.NullPointerException
at Server.processPackets(Server.java:398)
at PacketWorker.run(PacketWorker.java:43)
at java.lang.Thread.run(Thread.java:636)
processPackets 包含上面的代码。注释表示行数#
谢谢你启发我。