SSp*_*oke 8 java null try-catch nullpointerexception concurrenthashmap
之前我正在使用HashMap
public Map<SocketChannel, UserProfile> clients = new HashMap<SocketChannel, UserProfile>();
Run Code Online (Sandbox Code Playgroud)
现在我已经切换到ConcurrentHashMap以避免同步块,现在我遇到了问题,我的服务器每秒都有200-400个并发客户端,预计会随着时间的推移而增长.
现在看起来像这样
public ConcurrentHashMap<SocketChannel, UserProfile> clients = new ConcurrentHashMap<SocketChannel, UserProfile>();
Run Code Online (Sandbox Code Playgroud)
我的服务器设计就像这样.我有一个工作线程来处理大量的数据包.每个数据包都使用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++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的意思是我当然要通过在Iterator中添加一个try-catch Exception来跳过这些空客户端来修复它.
但我不明白,如果检查上面是否(人!= 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)
Run Code Online (Sandbox Code Playgroud)
processPackets包含上面的代码.并且注释表示行数#
谢谢你的启发.
Ste*_*n C 16
你需要阅读的javadoc的ConcurrentHashMap.values()方法,特别注意为迭代器是如何描述values()的收集工作:
"视图的迭代器是一个"弱一致"的迭代器,它永远不会抛出ConcurrentModificationException,并保证遍历构造迭代器时存在的元素,并且可能(但不保证)反映构造之后的任何修改.
迭代器不会为您提供值集合状态的一致快照,但它是线程安全的,并且明确指定了预期的行为范围.
如果您希望Map实现为您提供映射中值(或键或条目)的一致快照,并允许您同时进行修改,则可能需要创建自定义Map包装类(复制集合)原子地...或者是一个完整的自定义Map实现.对于您的用例,两者都可能比ConcurrentHashMap慢很多.