Background
I'm learning Java Socket on my own. I created a Socket Server and Client to run on localhost.
- Server uses a fixed-size threadpool of size 20 to handle connections.
- Client creates 50 threads and each sends 1000 connection requests to server one by one.
- I use a thread-safe object
ActiveCountto count the active server threads in each connection.
Behavior
After I start server and client, the ActiveCount object shows the number is stable at 20 for like 5 seconds and the requests are handled at good speed. Then the number starts to drop and reach to 1 active thread only and stuck for 3 seconds. Then due to this low performance, I got java.net.ConnectException: Operation timed out (Connection timed out).
Code
Server
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12031);
ActiveCount threadCount = new ActiveCount(); // for counting current active threads
Executor pool = Executors.newFixedThreadPool(20);
while (true) {
// accept connection and start thread
Socket clientSocket = serverSocket.accept();
pool.execute(() -> {
threadCount.incrementCount();
try {
// Some I/O operations here...
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String clientID = in.readLine();
System.out.println("Client ID is: " + clientID);
out.println("Active Server Thread Count = " + threadCount.getCount());
out.flush();
} catch (IOException e) {
System.err.println("Server has IO Exception: " + e);
} finally {
threadCount.decrementCount();
try { clientSocket.close(); } catch (IOException e) {}
System.out.println("Thread exiting");
}
});
}
}
Client
public class SocketClientMultithreaded {
static CyclicBarrier barrier;
public static void main(String[] args){
String hostName;
int port;
int numOfThreads = 50;
hostName= "localhost";
port = 12031; // default port in SocketServer
barrier = new CyclicBarrier(numOfThreads);
// start 50 SocketClientThread
for (int i = 0; i < numOfThreads; i++) {
Runnable runnable = () -> {
Socket s;
for (int j = 0; j < 1000; j++) { // send 1000 requests to the server socket
try {
s = new Socket(hostName, port);
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out.println("Client ID is " + Thread.currentThread().getId());
System.out.println(in.readLine()); // print the current active thread count sent from server
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
break;
} catch (IOException e) {
System.err.println("I/O connection exception: " + e);
break;
}
}
try {
System.out.println("Thread waiting at barrier");
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
Logger.getLogger(SocketClientThread.class.getName()).log(Level.SEVERE, null, e);
}
};
new Thread(runnable).start(); // start the thread
}
}
}
Terminal Terminal output
I suspects there may be some resource problem but the memory usage seems to low. I'm not sure why the thread number would drop and hope to get some help here. Really appreciate it!