Three Java TCP socket server implementations, each demonstrating a different concurrency model, plus a JMeter test plan for load testing them.
| Implementation | Location | Concurrency model |
|---|---|---|
| Single-threaded | SingleThreaded/Server.java | One thread handles all connections sequentially |
| Multi-threaded | MultiThreaded/Server.java | Spawns a new Thread per accepted connection |
| Thread pool | ThreadPool/Server.java | Fixed ExecutorService pool (size 10) handles connections |
All three listen on port 8010 and respond with a simple "Hello from server ..." message before closing the connection.
Each server is a standalone .java file with no external dependencies — just a JDK (8+) is required.
# Single-threaded
cd SingleThreaded
javac Server.java
java Server
# Multi-threaded
cd MultiThreaded
javac Server.java
java Server
# Thread pool
cd ThreadPool
javac Server.java
java ServerOnly run one server at a time, since they all bind to the same port (8010).
The repo includes JmeterClinetPoolTest.jmx, a JMeter test plan that opens raw TCP connections against localhost:8010 using a TCP Sampler (not HTTP, since these are raw socket servers).
Test plan defaults:
- Thread Group: up to 1,000,000 threads, 60s ramp-up, 1 loop, stops the thread on sample error
- TCP Sampler: connects to
localhost:8010, reuses the connection - Listeners: View Results Tree, View Results in Table, Graph Results
- Install Apache JMeter (5.6.3 or compatible).
- Start the server you want to test (see above) — leave it running in its own terminal.
- Open JMeter and load the test plan:
jmeter -t JmeterClinetPoolTest.jmx
- Before running, adjust the Thread Group's number of threads according to your PC's configuration (CPU cores, RAM). 1,000,000 threads is the plan's ceiling, not a recommended starting point — a machine with modest specs (e.g. 4 cores/8GB RAM) should start around 50–200 threads, while a beefier machine can push higher. Raise the count gradually and watch for errors/dropped connections before going further.
- Click Run. Watch the listeners:
- View Results Tree — inspect individual TCP responses/errors.
- View Results in Table — per-sample latency, connect time, bytes sent/received.
- Graph Results — throughput and response time over the run, useful for comparing servers.
- Stop the server, start the next implementation, and re-run the same test plan to compare results.
- Single-threaded: throughput should flatten quickly and latency should climb as concurrent connections queue up, since only one connection is served at a time.
- Multi-threaded: should handle much higher concurrency, but expect degraded performance or resource exhaustion at very high thread counts (unbounded thread creation).
- Thread pool: should hold steady latency/throughput under load up to the pool size (10), with requests queueing gracefully beyond that instead of spawning unbounded threads.