3 Using Multi – threading for networking
Pravin Jain
Introduction
In the last module, we have seen how networking can be done in Java. In that module we had seen a demo of using ServerSocket and Socket classes to create a simple EchoServer. The EchoServer developed in the previous module was able to accept connections from multiple clients, but it was able to service each client connection, one by one only. In this module we will look at how to create a multi-threaded EchoServer, which can handle multiple client connections in parallel.
What is a Thread?
Thread is a sequence of execution. When JVM starts there is one thread that executes the main method called the main thread. Java can have multiple threads executing in parallel. When JVM starts main is not the only thread executing We even have another thread for garbage collection, which is executing in parallel. So JVM is multi-threaded. Initially, main is the only non-daemon thread, the other threads related to Garbage collection are all daemon threads.
How do we create a new thread of execution in Java?
To create a new thread of execution, first we need to define a non-abstract class which implements the run method of a Runnable interface. This run method is the task which we want to be executed in parallel by this new thread of execution. Now the first step for creating the new thread of execution, is to create the instance of the class which implements Runnable Then create an instance of the class Thread by using the Runnable created in the previous step.
Next step is to setup the various properties on the object of Thread class created in previous step. Some of the common properties of the Thread class are, priority, name, daemon, etc. This step is optional, since we may like to use the default values of the properties The final step which creates the new thread of exection is to call the start() method on the object of the class. This final step creates a separate runtime stack where the exection of the run method of Runnable is initiated and executes parallel. The daemon property cannot be changed once the thread is started. On a thread instance start method can be called only once.
Demo for multi-threaded EchoServer.
Now we demonstrate how a multi-threaded EchoServer may be coded using Java threads. In this the main thread goes in a while true loop waiting for a client to connect. Whenever any client connects, it creates a new thread of execution to handle the client connection. The task to be done by the new thread of execution is in the form of a Runnable. This is as shown in figure.
Developing the Runnable
In our server application here, the task to handle the client involves reading each character from the client, displaying it locally and then sending it back to the client. ie. We echo the data back to the client. Lets call this as Echoer.
So we develop the class Echoer as an implementation of Runnable. This Echoer class has instance variables for an instance of Socket, InputStream and the OutputStream. In the constructor, we will initialize these variables and then in the run() method we go in a while loop, whick ends when a -1 is received indicating a disconnection from the client.
Source code of Echoer class
package org.epgpathshala.dad.net;
import java.net.ServerSocket; piamckpaogrtejoavrga.enpegt.pSaotchksheta;la.dad.net; import
java.io.IOException; imimppoortrtjajavvaa.n.ieot.ISnepruvteSrtSroeacmke;t;
imimppoortrtjajavvaa.n.ieot.OSouctpkuetS; tream; import java.io.IOException;
public class Echoer implements Runnable {
pubplircivcaltaessSEo ckheotSpehrvoenre;{ pprirvivaateteSIenrpvuetrSStorecakmet rbeocaeridv;er;
ppurbivliacteEcOhuotSpeurtvSetre(ianmt ptroarnt,simntitpteoro; lSize) throws IOException { this.board =
new ServerSocket(port);
}public Echoer(Socket s) throws IOException {
pubtlhicisv.pohidonreun=()s;throws IOException { wt hisle.r(etcrueeiv)e{r = s.getInputStream();
thSiso.tcrkaentspmhiottneer = sth.gise.tbOouatrpdu.atScctreepatm()(;);
} Echoer echoer = new Echoer(phone);
publTichvreoaid trhurne(a)d{= new Thread(echoer); tryth{read.start();
} int b = this.receiver.read();
} while (b != -1) {
public stSatyicstevmoi.doumt.apirni(nSt(tr(icnhga[r])ba)r;gs) throws IOException {
int portthi=s.Itnratengsmeri.tptaers.weIrnite(a(brg);s[0]);
EchoSber=vethrise. revceeriv=enr.erweadE(c)h; oServer(port); serv}er.run();
} this.phone.close();
} } catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
Developing the Server
In our server application here, the task for the main thread will be to start listening on the TCP/IP port and wait for a client to connect. Whenever a client connects we need to need to handle the client connection, for which we will need a separate thread. We can create the Runnable object to handle the client connection and continue accept the next connection. Lets call this as EchoServer.
So we develop the class EchoServer as a class with the main method . This EchoServer class has instance variables for an instance of ServerSocket. In the constructor, we will initialize the ServerSocket instance variable by calling the constructor of ServerSocket. We also have the run() method which is a while tru loop, accepting a new connection, starting a new thread thread t handle the connection, and then accepting the new connection again. The man method is simply used for creating the instance of EchoServer and calling the run method.
Source code of EchoServer class
you can view video on Using Multi – threading for networking |