Open kmansei opened 1 year ago
サーバーのメインスレッドは
while (true) {
var socket = serverSocket.accept();
var clientHandler = new ClientHandler(socket);
handlers.add(clientHandler);
executorService.execute(clientHandler);
}
serverSocket.accept()の部分でクライアントの接続が来るまでブロッキングされています。
サーバーが生成している各スレッドは
// クライアントからの投稿を待ち受ける
while ((message = reader.readLine()) != null) {
broadcast(message);
System.out.println(message);
}
reader.readLine()でユーザーから入力が来るまでブロックされています。
クライアントのメインスレッドは
while (true) {
input = scanner.nextLine();
:
:
}
scanner.nextLine()でブロックされています。
クライアントが生成しているスレッドは
while ((message = reader.readLine()) != null) {
System.out.println(message);
}
reader.readLine()の部分でブロックされています。
よって伝統的なwhile(true)のループとは異なり、ユーザーの入力待ちの間はCPUリソースは消費されないと考えます。
しかしながらも、クライアントが退室するまでclienthanderのスレッドは解放されないため、
Executors.newCachedThreadPool();
を使用しているもののクライアントから新たな接続があるたびにClientHandlerのスレッドを生成していると思われます。
実際に上記を
Executors.newFixedThreadPool(1);
と置き換えたところ、ある一つのclienthandlerが上記のスレッドプールを占有してしまい、他のクライアントからの入力を受け取ることができませんでした。
よってeaaa1f4では、クライアントが接続するたびにサーバーはスレッドを生成しているため、初期実装と余り接続できる数は変わらないと考えます。
Executor Serviceを使用時の実装コードは下記の通り eaaa1f4
サーバー
クライアント