我之前使用的是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),那么嵌套的代码不应该自动工作吗?
如果它不工作,那就意味着在迭代时已经移除了该项,但这应该是不可能的,因为它是线程安全的,怎么回事?
我该怎么做?还是使用try-catch异常是最好的方法?
这里是异常信息:
java.lang.NullPointerException
at Server.processPackets(Server.java:398)
at PacketWorker.run(PacketWorker.java:43)
at java.lang.Thread.run(Thread.java:636)
processPackets函数包含上述代码,注释中标注了行数 #。
感谢您的启示。