以前は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例外を追加して、これらのnullクライアントをスキップすることで修正します。
しかし、上記の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には、上記のコードが含まれています。コメントは行数を示します#
私を啓発してくれてありがとう。