I'm trying to implement a really simple echo-back multi-threaded server.
I used the thread pool created with newFixedThreadPool, but it looks like the number of concurrent connections is fixed at nThreads (passed into newFixedThreadPool). For example, if I set nThreads to 3, then the fourth client that connects cannot interact with the server.
This is rather weird because the documentation says "Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue."
Since the documentation also says that "If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available." I suspect my threads are never "released" so that they never became available for reuse.
I think this could be a silly mistake, but I couldn't figure out what's wrong. Here's my client handler's run() method, which I think is very similar to the code found here (client below is just a Socket connected to the client):
@Override
public void run() {
try(BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))) {
String input;
while(true) {
input = readLine();
if(input == null)
break;
out.write(input);
out.newLine();
out.flush();
}
} catch(IOException e) {
System.err.println(e, "Error from socket IO.");
System.exit(1);
}
try {
client.close();
} catch(IOException e) {
System.err.println(e, "Error when closing socket.");
System.exit(1);
}
System.out.println("Client " + client.getInetAddress().getHostAddress() +
" closed connection.\n");
}
EDIT 1: I guess I should clarify that clients will immediately disconnect after receiving the response. So the threads should become available very soon.
EDIT 2: Here's the code that handles connection (listen is a ServerSocket):
while(true) {
Socket client = null;
try {
client = listen.accept();
} catch(IOException e) {
System.err.println(e, "Error when waiting for connection.");
System.exit(1);
}
System.out.println("New connection from client: " +
client.getInetAddress().getHostAddress() + "\n"
);
threadPool.execute(new ConnectionHandler(client));
}
This is the thread pool initialization (in the constructor): this.threadPool = Executors.newCachedThreadPool();.
EDIT 3: Log messages (when nThread = 3, so the fourth connection is never really handled):
New connection from client: 127.0.0.1
Client 127.0.0.1 closed connection.
New connection from client: 127.0.0.1
Client 127.0.0.1 closed connection.
New connection from client: 127.0.0.1
Client 127.0.0.1 closed connection.
New connection from client: 127.0.0.1