I was using HashMap before like
public Map<SocketChannel, UserProfile> clients = new HashMap<SocketChannel, UserProfile>();
now I've switched to ConcurrentHashMap to avoid synchronized blocks and now i'm experiencing problems my server is heavily loaded with 200-400 concurrent clients every second which is expected to grow over time.
which now looks like this
public ConcurrentHashMap<SocketChannel, UserProfile> clients = new ConcurrentHashMap<SocketChannel, UserProfile>();
My server design works like this. I have a worker thread(s) for processing huge amounts of packets. Each packet is checked with a packetHandler sub-routine (not part of thread) pretty much any client can call it at anytime it's almost like static but it isn't.
My whole server is mostly single threaded except for the packet processing portion.
Anyways so when someone uses a command like count up all clients online and get some information from them.
It is also possible that clients can get disconnected and removed from ConcurrentHashMap while the counting is in progress (which causes my problems).
Also I'd like to add some code here.
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++;
}
}
}
I mean of course i'm going to fix it by adding a try-catch Exception inside the Iterator to skip these null clients.
But what I don't understand if it checks above if(person != null) shouldn't the code nested automatically works..
if it doesn't means it got removed while it was iterating which should be impossible since it's thread safe wtf?
What should I do? or is try-catch Exception the best way?
Here is the exception
java.lang.NullPointerException
at Server.processPackets(Server.java:398)
at PacketWorker.run(PacketWorker.java:43)
at java.lang.Thread.run(Thread.java:636)
The processPackets contains the code above. and the comment indicates the line count #
Thanks for enlightening me.