1

I have a following code snippet to make my HttpServer a multithreaded one,but its still working as single threaded.Can you please help me out? I'm using Java HttpServer API :

// Bind to port 8083
httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);

// Adding '/send' context
httpServer.createContext("/send", new SendHandler());

ExecutorService executor = Executors.newCachedThreadPool();
httpServer.setExecutor(executor);

// Start the server
httpServer.start();

Full Java Class :

public class GCMMockServer {

    static HttpServer httpServer;
    static final int HTTP_PORT = 8083;

    public static void main(String[] args) {
        GCMMockServer.start();
    }

    public static void start() {
        try {
            // Bind to port 8083
            httpServer = HttpServer.create(new InetSocketAddress(HTTP_PORT), 0);

            // Adding '/send' context
            httpServer.createContext("/send", new SendHandler());

            ExecutorService executor = Executors.newCachedThreadPool();
            httpServer.setExecutor(executor);

            // Start the server
            httpServer.start();

            System.out.println("GCM Mock Server started at (localhost,8083)");
        } catch (IOException ex) {
            Logger.getLogger(GCMMockServer.class.getName()).log(Level.SEVERE,
                    null, ex);
        }
    }

    public static void stop() {
        httpServer.stop(5);
    }

    // Handler for '/send' context
    static class SendHandler implements HttpHandler {

        @Override
        public void handle(HttpExchange he) throws IOException {
            System.out.println("Serving the request");

            // Serve for POST requests only
            if (he.getRequestMethod().equalsIgnoreCase("POST")) {

                try {
                    // REQUEST Headers
                    Headers requestHeaders = he.getRequestHeaders();
                    Set<Map.Entry<String, List<String>>> entries = requestHeaders
                            .entrySet();

                    System.out.println("Inside POST method");

                    int contentLength = Integer.parseInt(requestHeaders
                            .getFirst("Content-length"));
                    List<String> contentTypes = null;

                    for (Iterator<Entry<String, List<String>>> iterator = entries
                            .iterator(); iterator.hasNext();) {
                        Entry<String, List<String>> entry = iterator.next();
                        String key = entry.getKey();
                        System.out.println("Key : " + key + ", values : ");
                        if (key.equalsIgnoreCase("Content-type")) {
                            contentTypes = entry.getValue();
                        }
                        for (Iterator<String> iterator2 = entry.getValue()
                                .iterator(); iterator2.hasNext();) {
                            String value = iterator2.next();
                            System.out.println("-----------" + value);
                        }
                    }

                    System.out.println("Content length : " + contentLength);

                    // REQUEST Body
                    InputStream is = he.getRequestBody();

                    if (contentTypes.contains("application/json")) {

                        InputStreamReader isr = new InputStreamReader(is,
                                "utf-8");
                        BufferedReader br = new BufferedReader(isr);

                        // From now on, the right way of moving from bytes to
                        // utf-8 characters:

                        int b;
                        StringBuilder buf = new StringBuilder(512);
                        while ((b = br.read()) != -1) {
                            buf.append((char) b);
                        }

                        JSONObject req = new JSONObject(buf.toString());
                        System.out.println("Request body : " + req);
                        String to = (String) req.get("to");
                        String message = (String) ((JSONObject) req.get("data"))
                                .get("message");
                        System.out.println("Request message : " + message
                                + ", to : " + to);
                    }

                    // RESPONSE Headers
                    Headers responseHeaders = he.getResponseHeaders();
                    System.out.println("Response Headers : "
                            + responseHeaders.toString());

                    String response = "Message received";
                    // Send RESPONSE Headers
                    he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
                            response.length());

                    // RESPONSE Body
                    OutputStream os = he.getResponseBody();

                    os.write(response.getBytes());

                    is.close();
                    os.flush();
                    os.close();
                    he.close();

                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (he.getRequestMethod().equalsIgnoreCase("GET")) {
                System.out.println("Nothing to serve in GET request type");

                // RESPONSE Headers
                Headers responseHeaders = he.getResponseHeaders();
                String response = "Hi This is Sandeep";
                System.out.println("Response Headers : "
                        + responseHeaders.toString());

                // Send RESPONSE Headers
                he.sendResponseHeaders(HttpURLConnection.HTTP_OK,
                        response.length());

                // RESPONSE Body
                OutputStream os = he.getResponseBody();
                OutputStreamWriter osw = new OutputStreamWriter(os);

                osw.write(response);

                // is.close();
                osw.close();
                os.close();
                he.close();
            }

        }
    }
}
10
  • 1
    How do you figure it's only one? Cah you share SendHandler? Do you print out thread name in it? How do you load-test it? Commented Dec 21, 2015 at 8:14
  • Here is my whole Java file : Commented Dec 21, 2015 at 8:35
  • please edit your question, don't post in comment Commented Dec 21, 2015 at 8:35
  • I'm sending post requests from another test class in a for loop (with some sleep b/w a request and the following one).All the requests are being processed in the same order using the log statements on server side.By that I could deduce that its being processed in SingleThread Commented Dec 21, 2015 at 8:42
  • 1
    That test sends requests sequentially. Without a test case that sends requests in parallel, there is no evidence here whatsoever that your server doesn't process in parallel. Commented Dec 21, 2015 at 8:49

1 Answer 1

1

Consider changing the start of your handle method:

 @Override
 public void handle(HttpExchange he) throws IOException {
    System.out.println("Serving the request from Thread "
          + Thread.currentThread().getName() + " / " 
          + Thread.currentThread().getId());
    try {
      Thread.sleep(5000);
    } catch(InterruptedException ie) {
       ie.printStackTrace();
       return;
    }
    System.out.println("Continue request in Thread "
          + Thread.currentThread().getName() + " / " 
          + Thread.currentThread().getId());

Now start the server, open up a browser, load your url, refresh twise within 5s and watch your console log.

I have a feeling you'll be seeing multiple threads just fine.

Regarding your test:

The Test you use is single threaded (a for-loop). So there will be only one active invocation of your servlet at any one time. As the next iteration of your for loop will only start once the last one is finished, the previous thread in the executor thread pool was recycled. There simply was no need for mutlithreading based on your test.

Sign up to request clarification or add additional context in comments.

3 Comments

Thankyou very much @Jan for the answer with an example to verify as well.And thank you to everyone else for the answers as well. Yes for my test case,there is no need of multithreading.I'm writing a test case where there will be multiple requests from multiple running threads calling this HttpServer.
Fine. Whenever you'r ready it would be nice if you accepted an answer to your question.
Done.Sorry I have forgot about that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.