Multithreaded Servers in Java
Last Updated :
09 Nov, 2020
Prerequisites: Socket Programming in Java
Multithreaded Server: A server having more than one thread is known as Multithreaded Server. When a client sends the request, a thread is generated through which a user can communicate with the server. We need to generate multiple threads to accept multiple requests from multiple clients at the same time.

Advantages of Multithreaded Server:
- Quick and Efficient: Multithreaded server could respond efficiently and quickly to the increasing client queries quickly.
- Waiting time for users decreases: In a single-threaded server, other users had to wait until the running process gets completed but in multithreaded servers, all users can get a response at a single time so no user has to wait for other processes to finish.
- Threads are independent of each other: There is no relation between any two threads. When a client is connected a new thread is generated every time.
- The issue in one thread does not affect other threads: If any error occurs in any of the threads then no other thread is disturbed, all other processes keep running normally. In a single-threaded server, every other client had to wait if any problem occurs in the thread.
Disadvantages of Multithreaded Server:
- Complicated Code: It is difficult to write the code of the multithreaded server. These programs can not be created easily
- Debugging is difficult: Analyzing the main reason and origin of the error is difficult.
Quick Overview
We create two java files, Client.java and Server.java. Client file contains only one class Client (for creating a client). Server file has two classes, Server(creates a server) and ClientHandler(handles clients using multithreading).

Client-Side Program: A client can communicate with a server using this code. This involves
- Establish a Socket Connection
- Communication
Java
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
// establish a connection by providing host and port
// number
try (Socket socket = new Socket("localhost", 1234)) {
// writing to server
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
// reading from server
BufferedReader in
= new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// object of scanner class
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
// reading from user
line = sc.nextLine();
// sending the user input to server
out.println(line);
out.flush();
// displaying server reply
System.out.println("Server replied "
+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Server-Side Program: When a new client is connected, and he sends the message to the server.
1. Server class: The steps involved on the server side are similar to the article Socket Programming in Java with a slight change to create the thread object after obtaining the streams and port number.
- Establishing the Connection: Server socket object is initialized and inside a while loop a socket object continuously accepts an incoming connection.
- Obtaining the Streams: The inputstream object and outputstream object is extracted from the current requests’ socket object.
- Creating a handler object: After obtaining the streams and port number, a new clientHandler object (the above class) is created with these parameters.
- Invoking the start() method: The start() method is invoked on this newly created thread object.
2. ClientHandler class: As we will be using separate threads for each request, let's understand the working and implementation of the ClientHandler class implementing Runnable. An object of this class acts as a Runnable target for a new thread.
- First, this class implements Runnable interface so that it can be passed as a Runnable target while creating a new Thread.
- Secondly, the constructor of this class takes a parameter, which can uniquely identify any incoming request, i.e. a Socket.
- Inside the run() method of this class, it reads the client's message and replies.
Java
import java.io.*;
import java.net.*;
// Server class
class Server {
public static void main(String[] args)
{
ServerSocket server = null;
try {
// server is listening on port 1234
server = new ServerSocket(1234);
server.setReuseAddress(true);
// running infinite loop for getting
// client request
while (true) {
// socket object to receive incoming client
// requests
Socket client = server.accept();
// Displaying that new client is connected
// to server
System.out.println("New client connected"
+ client.getInetAddress()
.getHostAddress());
// create a new thread object
ClientHandler clientSock
= new ClientHandler(client);
// This thread will handle the client
// separately
new Thread(clientSock).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
// Constructor
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
// get the outputstream of client
out = new PrintWriter(
clientSocket.getOutputStream(), true);
// get the inputstream of client
in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
// writing the received message from
// client
System.out.printf(
" Sent from the client: %s\n",
line);
out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
clientSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Steps:
- Compile both Client and Server programs.
- Run the server first and then the Client.
Output
Similar Reads
Multithreading in Java Multithreading is a Java feature that allows the concurrent execution of two or more parts of a program for maximum utilization of the CPU. Each part of such a program is called a thread. So, threads are lightweight processes within a process.Different Ways to Create ThreadsThreads can be created by
3 min read
SimpleFileServer in Java A server is a computer that is dedicated solely to the purpose of serving. It serves files to its clients whenever requests are made, and it should always be available. A program running on a port within the server is used to handle requests. The term 'server' can refer to a physical or virtual comp
7 min read
Main thread in Java Java provides built-in support for multithreaded programming. A multi-threaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution.When a Java program starts up, one thread begins running i
4 min read
Virtual Threads in Java In Java, Virtual threads are now supported by the Java Platform. Virtual threads are lightweight threads that greatly minimize the effort required to create, operate, and manage high volumes systems that are concurrent. As a result, they are more efficient and scalable than standard platform threads
8 min read
Deadlock in Java Multithreading Deadlock occurs in Java when multiple threads block each other while waiting for locks held by one another. To prevent deadlocks, we can use the synchronized keyword to make methods or blocks thread-safe which means only one thread can have the lock of the synchronized method and use it, other threa
4 min read
Java Threads Java threads are lightweight subprocesses, representing the smallest unit of execution with separate paths. The main advantage of multiple threads is efficiency (allowing multiple things at the same time). For example, in MS Word, one thread automatically formats the document while another thread is
11 min read
Non Blocking Server in Java NIO Java NIO(New Input/Output) is high-performance networking and file handling API and structure which works as an alternative IO API for Java. It is introduced from JDK 4 which works as the second I/O system after standard Java IO with some added advanced features. It provides enhanced support for fil
8 min read
Legacy Socket API in Java The Java Socket API has been around for more than two decades. It has been maintained and updated over that period, but even the most well-kept code ultimately has to be upgraded to stay up with contemporary technologies. The fundamental classes that handle Socket interaction in Java 13 have been re
4 min read
Producer-Consumer Solution using Threads in Java In computing, the producer-consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, which share a common, fixed-size buffer used as a queue. The producer's job is t
6 min read