Java ProgrammingLearn How to create a multi-threaded Server in Java

Learn How to create a multi-threaded Server in Java

Java programming is a very versatile programming language. It can be used to create a powerful server easily. You can create a single server or a single client connection by using Java socket APIs. However, in this article, we will discuss about building a multi-threaded server in Java. We will discuss the techniques which will be required to create the server and we will also know more about multithreading and related concepts. Also, we will learn about the advantages and the disadvantages of using a multi-threaded server in Java.

Let’s have a look at some of the important concepts of multi-threading.

What is multi-threading?
Often, the term “multi-threading” is considered to be synonymous with similar sounding terms like “multi-programming” or “multi-tasking”. However, these terms actually have a very different meaning.

Actually, multi-threading defines the capability of a software, an operating system, a process or a hardware component to manage more than one user at a time. Such an application can accept multiple requests by one user or many users without running multiple instances of the program on the computer. Another speciality of such programs is that they record any request of the user as a thread, where the users includes other programs too. Each thread has a special identity so that the application can easily keep track of the commands given to it. Multi-threaded applications keep a track of the requests and also the status of work assigned to each thread, until the work is completed.

Thus, a thread is nothing but a sub-process which doesn’t take up much system resources. It is the smallest unit of computing. Multi-threading and multi-processing are the main features of multi-tasking.

However, we use multi-threading more often because it has multiple advantages over multi-processing. The threads in multi-threading has a common area in the computer memory. They do not need separate memory spaces. Thus, they save memory resources of the system. Also, switching contexts take much lesser time in the case of threads than in processes.

Sockets and threads – Conceptual idea
A socket is an end-point of the connection between two programs running on a network. This end-point is required to establish a communication link between a server program and a client program. These programs run on different computers which are called local and remote computers. But, these two programs can also be run on a single computer.

Actually, the socket links a server program to the port on the computer on which it is running, so any program which is on the network and has the same port for the socket can communicate with the server easily. The server actually provides resources for the client programs on the network. The client programs send requests for the services they require to the server program, and the server program responds accordingly.

The easiest and the fastest way of handling these requests are to create a multi-threaded server program. Such a server program creates a thread for every request it receives from the client programs. The thread is a set of instructions which run differently from the program or other such threads. Using this, a server can easily multitask well. It can start a thread for a client and then continue communicating with other programs/threads.

What are the advantages of a multi-threaded server?
The main advantages of using a multi-threaded server over a single-threaded one in Java are given below:

  • It is very quick and doesn’t obstruct the user, as every thread is independent of each other and the program. Thus, the server can respond to many queries at once.
  • As threads are independent of each other, they do not block the work of other threads if exceptions occur in the thread.
  • As it can perform many operations at once, it can save lots of time.
  • If a process runs for a long time then single-threaded servers may become unresponsive, but this is not the case in multi-threaded servers.

What are the disadvantages?
While there are many advantages to multi-threaded programs, there are some disadvantages too. Some of these are given below:

  • Difficult to write: Creating multi-threaded programs are not very easy. Only professionals can do this work nicely.
  • Difficult to debug: Finding the main cause of an error in a multi-threaded program is very difficult.
  • Testing constraints: As the errors in a multi-threaded program are mostly related to the ‘timing’, it is very hard to test compared to a single-threaded program.

But, now there are multiple frameworks available in Java like ‘executor’, ‘fork/join’ etc. And it makes multi-threading simple to manage.

How to write a multi-threaded server?

Multi-threaded server can be created in different ways. Here we will be implementing Runnable interface and socket programming.
Now let’s dive into the code to understand the implementation. We will have three components to implement the multi-threading. The first one is the server program, second one is the worker thread which is executing the client request and the last one is the client program which is initiating multiple threads as per requirement.

The server program accepts client request and delegate it to the worker thread. Now the worker thread actually executes the request. In the meantime server can take multiple client requests and start the processing. So individual threads will be started and they will work in parallel.
Java Programming Course for Beginner From Scratch
Listing 1: The server program

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;

public class ServerMultithreaded implements Runnable{
    protected int          serverPortVal   = 8080;
    protected ServerSocket serverSocketVal = null;
    protected boolean      hasStopped    = false;
    protected Thread       movingThread= null;

    public ServerMultithreaded(int port){
        this.serverPortVal = port;
    }

    public void run(){
        synchronized(this){
            this.movingThread = Thread.currentThread();
        }
        opnSvrSocket();
        while(! hasStopped()){
            Socket clntSocket = null;
            try {
                clntSocket = this.serverSocketVal.accept();
            } catch (IOException e) {
                if(hasStopped()) {
                    System.out.println("Server has Stopped...Please check") ;
                    return;
                }
                throw new RuntimeException(
                    "Client cannot be connected - Error", e);
            }
            new Thread(
                new WrkrRunnable(
                    clntSocket, "This is a multithreaded Server")
            ).start();
        }
        System.out.println("Server has Stopped...Please check") ;
    }
    private synchronized boolean hasStopped() {
        return this.hasStopped;
    }
    public synchronized void stop(){
        this.hasStopped = true;
        try {
            this.serverSocketVal.close();
        } catch (IOException e) {
            throw new RuntimeException("Server can not be closed - Please check error", e);
        }
    }
    private void opnSvrSocket() {
        try {
            this.serverSocketVal = new serverSocketVal(this.serverPortVal);
        } catch (IOException e) {
            throw new RuntimeException("Not able to open the port 8080", e);
        }
    }

}

Now, the next one is the worker program. It receives the request from the server program and process individual client request.

Listing 2: The worker thread

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;

public class WrkrRunnable implements Runnable{
    protected Socket clntSocket = null;
    protected String txtFrmSrvr   = null;

    public WrkrRunnable(Socket clntSocket, String txtFrmSrvr) {
        this.clntSocket = clntSocket;
        this.txtFrmSrvr   = txtFrmSrvr;
    }
    public void run() {
        try {
            InputStream inputstrm  = clntSocket.getInputStream();
            OutputStream outputstrm = clntSocket.getOutputStream();
            long timetaken = System.currentTimeMillis();
            outputstrm.write(("OK\n\nWrkrRunnable: " + this.txtFrmSrvr + " - " +timetaken +"").getBytes());
            outputstrm.close();
            inputstrm.close();
            System.out.println("Your request has processed in time : " + timetaken);
        } catch (IOException e) {           
            e.printStackTrace();
        }
    }
}

Following is the code which is a part of the client program to start multithreading.

Listing 3: Client code to start multiple threads

Public class Client{
publics static void main(String [] agrs) throws IOException{
ServerMultithreaded newServer = new ServerMultithreaded(9191);
new Thread(newServer).start();

try {
    Thread.sleep(15 * 1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println("Stopping newServer");
newServer.stop();
}
}

Conclusion:
A multi-threaded server is the need of the hour in this fast going world. Such a server can respond to its client’s queries very quickly and efficiently. However, creating such a server isn’t easy, so this article has discussed all the aspects of creating the server, from major concepts to the process itself. This guide, if followed closely, can easily help you create a good multi-threaded server in Java.

2 COMMENTS

  1. Hello sir
    This is very nice and useful post about multi-threading .

    Thank You for this post
    Keep posting for us.

  2. This code contains multiple errors
    in the opnSvrSocket() method

    this.serverSocketVal = new serverSocketVal(this.serverPortVal);

    should be changed to
    this.serverSocketVal = new ServerSocket(this.serverPortVal);

    and
    Listing 3: Client code to start multiple threads

    Public class Client{
    publics static void main(String [] agrs) throws IOException{
    ServerMultithreaded newServer = new ServerMultithreaded(9191);
    new Thread(newServer).start();

    try {
    Thread.sleep(15 * 1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println(“Stopping newServer”);
    newServer.stop();
    }
    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14
    Public class Client{
    publics static void main(String [] agrs) throws IOException{

    furthermore the ‘client code to start multiple threads’ is server start code.
    to initiate clients tell your pupils to use a browser with an adress http://localhost:9191

    should be
    public class Client{
    public static void main(String [] agrs) throws IOException{

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -