Site Search:

6.1 Executing tasks in threads

SingleThreadedWebServer can handle only one request at a time. The main thread alternates between accepting connections and processing he associated request. While the server is handling a request, new connections must wait until it finishes the current request and calls accept again.

DemoServer>cat DemoWebServer.java 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class DemoWebServer {
    public static void main(String[] args) throws IOException {
        
        try(ServerSocket socket = new ServerSocket(8090)) {
            while (true) {
                Socket connection = socket.accept();
                handleRequest(connection);
                //new Thread(() -> handleRequest(connection)).start();
            }
        }
    }

    private static void handleRequest(Socket connection) {
        System.out.println(Thread.currentThread().toString() + connection.getInetAddress());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
DemoServer>javac DemoWebServer.java 
DemoServer>java DemoWebServer
Thread[main,5,main]/0:0:0:0:0:0:0:1
Thread[main,5,main]/0:0:0:0:0:0:0:1
Thread[main,5,main]/0:0:0:0:0:0:0:1
Thread[main,5,main]/0:0:0:0:0:0:0:1
Thread[main,5,main]/0:0:0:0:0:0:0:1

^C


DemoClient>date;for i in {1..5}; do curl localhost:8090& done;wait;date
Tue Jul 18 23:47:20 EDT 2017
[1] 2716
[2] 2717
[3] 2718
[4] 2719
[5] 2720
curl: (52) Empty reply from server
[1]   Exit 52                 curl localhost:8090
curl: (52) Empty reply from server
[2]   Exit 52                 curl localhost:8090
curl: (52) Empty reply from server
curl: (52) Empty reply from server
[3]   Exit 52                 curl localhost:8090
[4]-  Exit 52                 curl localhost:8090
curl: (52) Empty reply from server
[5]+  Exit 52                 curl localhost:8090
Tue Jul 18 23:47:30 EDT 2017

DemoClient>

A more responsive approach is to create a new thread for servicing each request.
The main thread still alternates between accepting an incoming connection and dispatching the request. The difference is that for each connection, the main loop creates a new thread to process the request instead of processing it within the main thread. As a result, the performance improvement is 10 fold.

DemoServer>cat DemoWebServer.java 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class DemoWebServer {
    public static void main(String[] args) throws IOException {
        
        try(ServerSocket socket = new ServerSocket(8090)) {
            while (true) {
                Socket connection = socket.accept();
                //handleRequest(connection);
                new Thread(() -> handleRequest(connection)).start();
            }
        }
    }

    private static void handleRequest(Socket connection) {
        System.out.println(Thread.currentThread().toString() + connection.getInetAddress());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }
        try {
            connection.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
DemoServer>javac DemoWebServer.java 
DemoServer>java DemoWebServer
Thread[Thread-0,5,main]/0:0:0:0:0:0:0:1
Thread[Thread-2,5,main]/0:0:0:0:0:0:0:1
Thread[Thread-1,5,main]/0:0:0:0:0:0:0:1
Thread[Thread-3,5,main]/0:0:0:0:0:0:0:1
Thread[Thread-4,5,main]/0:0:0:0:0:0:0:1

^C


DemoClient>date;for i in {1..5}; do curl localhost:8090& done;wait;date
Tue Jul 18 23:50:32 EDT 2017
[1] 2734
[2] 2735
[3] 2736
[4] 2737
[5] 2738
curl: (52) Empty reply from server
curl: (52) Empty reply from server
curl: (52) Empty reply from server
curl: (52) Empty reply from server
[1]   Exit 52                 curl localhost:8090
[2]   Exit 52                 curl localhost:8090
[5]+  Exit 52                 curl localhost:8090
curl: (52) Empty reply from server
[3]-  Exit 52                 curl localhost:8090
[4]+  Exit 52                 curl localhost:8090
Tue Jul 18 23:50:34 EDT 2017
DemoClient>