In this exercise, you will learn how to create a pool of threads using the ThreadPoolExecutor
class. You also will learn how these pool of threads are used to execute tasks.
(1.1) Build and run a server that receives connection request (using
ThreadPoolExecutor)
• Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
• Under Choose Project pane, select General under Categories and Java
Application under Projects. Click Next.
• Under Name and Location pane, for the Project Name field, type in
ServerUsingThreadPoolExecutor as project name.
• For Create Main Class field, type in ServerUsingThreadPoolExecutor. (Figure-
1.10 below)
• Click Finish.
This class acts as a listener on an IP port and echo characters sent to it when a connection is
made. This is similar in functionality to a web server type application. Since we want to be able
to handle lots of short living connections simultaneously, we would create a separate thread of
execution for each connection. Since thread creation is a costly operation to the JVM, the best
way to achieve this is to create and use a pool of threads. A thread in this pool then can be re-
used by a new connection when a previous connection is done with it.
/**
* Constructor
**/
public ServerUsingThreadPoolExecutor(int port, int poolSize) throws IOException {
/* Create a new ServerSocket to listen for incoming connections */
serverSocket = new ServerSocket(port);
/**
* Service requests
**/
public void serviceRequests() {
int count = 1;
int qLength = 0;
try {
for (;;) {
if ((qLength = workQueue.size()) > 0)
System.out.println("Queue length is " + qLength);
2
pool.execute(new ConnectionHandler(serverSocket.accept(), count++));
}
} catch (IOException ioe) {
System.out.println("IO Error in ConnectionHandler: " + ioe.getMessage());
pool.shutdown();
}
}
/**
* Main entry point
*
* @param args Command line arguments
**/
public static void main(String[] args) {
System.out.println("Listening for connections...");
ServerUsingThreadPoolExecutor ce = null;
try {
ce = new ServerUsingThreadPoolExecutor(8100, 4);
/*
* Serve incoming connection request until interrupted.
*/
ce.serviceRequests();
} catch (IOException ioe) {
System.out.println("IO Error creating listener: " + ioe.getMessage());
}
}
}
Code-1.11: ServerUsingThreadPoolExecutor.java
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
/**
* Constructor
*
* @param socket The socket on which incoming data will arrive
3
**/
public ConnectionHandler(Socket socket, int connectionID) {
this.socket = socket;
this.connectionID = connectionID;
}
/**
* run method to do the work of the handler
**/
public void run() {
System.out.println("Connection " + connectionID + ", started");
try {
InputStream is = socket.getInputStream();
/* If the number of bytes read is less than zero then the connection
* has been terminated so we end the thread
*/
if (is.read(inData) < 0)
break;
4
Trouble-shooting: If you see the following error condition, it is highly likely due to the fact that
you have not terminate the server process that uses the same port - port 8100 in this example.
Solution: Terminate the previously started process that uses the same port. Click Runtime tab
window and expand Processes node and then right click the process and select Terminate
Process. Or as a brutal method, exiting the NetBeans IDE will do it as well. Also you can use
the different port number other than 8100. In this case, you will also need to change the hard-
coded port number of the client.
• Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
• Under Choose Project pane, select General under Categories and Java
Application under Projects. Click Next.
• Under Name and Location pane, for the Project Name field, type in
ConnectionClient as project name.
• For Create Main Class field, type in ConnectionClient.
• Click Finish.
2. Modify the IDE generated ConnectionClient.java as shown in Code-1.21 below. Study the
code by paying special attention to the bold fonted parts.
import java.net.*;
import java.io.*;
import java.util.concurrent.*;
/**
* ConnectionClient pass characters from the keyboard to a socket. Simplified version of
5
* telnet
*/
public class ConnectionClient {
/**
* Main entry point
*
* @param args Command line arguments
**/
public static void main(String[] args) {
String host = null;
int port = 0;
if (args.length < 2) {
host = "127.0.0.1";
port = 8100;
}
OutputStream os = null;
try {
// The Socket() call returns only when the connection
// request from this client is accepted by the server.
Socket s = new Socket(host, port);
os = s.getOutputStream();
System.out.println("Connection established to server. Type characters and press
<ENTER> to send");
System.out.println("Type EXIT and press <RETURN> to exit");
/* Read data from the standard input and send it to the remote socket */
while (true) {
byte[] inData = new byte[100];
System.in.read(inData);
String inString = new String(inData);
if (inString.substring(0, 4).compareTo("EXIT") == 0)
System.exit(1);
os.write(inData);
}
} catch (Exception e) {
System.out.println("Failed to connect to remote host: " +
e.getMessage());
}
}
6
}
Code-1.21: ConnectionClient.java
• Enter some value into the Input field and press Enter key. (Figure-1.25 below) In
this example, "This is a message from ConnectionClient instance 1" is entered.
7
Figure-1.25: Enter a message
Trouble-shooting: If you see the following error condition, it is highly likely due to the fact that
you have not started the server or firewall blocks the connection request.
9
Figure-1.26: Connection request from ConnectionClient is received and message from
ConnectionClient is displayed
• Right click ConnectionClient project and select Run Project. This will start the
2nd instance of the ConnectionClient.
• Observe the result in the Output window. (Figure-1.23 below)
• Enter some value into the Input field and press Enter key. (Figure-1.27 below) In
this example, "Message from the 2nd instance of ConnectionClient by Sang Shin"
is entered.
10
Figure-1.27: Enter data from the 2nd instance of ConnectionClient
11
Figure-1.28: Connection request from ConnectionClient is received and message from
ConnectionClient is displayed
12