我之前使用过 HashMap
public Map<SocketChannel, UserProfile> clients = new HashMap<SocketChannel, UserProfile>();
现在我已经切换到 ConcurrentHashMap 以避免同步块,现在我遇到了问题,我的服务器每秒负载有 200-400 个并发客户端,预计会随着时间的推移而增长。
现在看起来像这样
public ConcurrentHashMap<SocketChannel, UserProfile> clients = new ConcurrentHashMap<SocketChannel, UserProfile>();
我的服务器设计是这样工作的。我有一个用于处理大量数据包的工作线程。每个数据包都使用一个 packetHandler 子例程(不是线程的一部分)进行检查,几乎任何客户端都可以随时调用它,它几乎就像是静态的,但事实并非如此。
除了数据包处理部分,我的整个服务器大部分都是单线程的。
无论如何,所以当有人使用诸如统计所有在线客户并从他们那里获取一些信息之类的命令时。
在计数进行时,客户端也可能会断开连接并从ConcurrentHashMap中删除(这会导致我的问题)。
另外我想在这里添加一些代码。
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 包含上面的代码。并且注释表示行数#
谢谢你启发我。