Can I make a Java HttpServer threaded/process requests in parallel?
Asked Answered
P

2

12

I have built a simple HttpServer following tutorials i have found online, using Sun's lightweight HttpServer.

Basically the main function looks like this:

public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        //Create the context for the server.
        server.createContext("/", new BaseHandler());

        server.setExecutor(null); // creates a default executor
        server.start();
    }

And I have implemented the BaseHandler Interface's method to process the Http request and return a response.

static class BaseHandler implements HttpHandler {
        //Handler method
        public void handle(HttpExchange t) throws IOException {

          //Implementation of http request processing
          //Read the request, get the parameters and print them
          //in the console, then build a response and send it back.
        }
  }

I have also created a Client that sends multiple requests via threads. Each thread sends the following request to the server:

http://localhost:8000/[context]?int="+threadID

On Each client run, The requests seem to arrive in different order to the server, but they are served in a serial manner.

What i wish to acomplish is for the requests to be processed in a parallel manner if that is possible.

Is it possible, for example, to run each handler in a seperate thread, and if so, is it a good thing to do.

Or should i just drop using Sun's lightweight server altogether and focus an building something from scratch?

Thanks for any help.

Pleasant answered 6/2, 2013 at 12:47 Comment(4)
That's what the HttpServer already does.Midpoint
This is done by setting the executor, see docs.oracle.com/javase/6/docs/api/java/util/concurrent/…Malherbe
If this is anything but a learning project, I would recommend looking at libraries like Apache Mina or Netty.Lenticel
Thanks for the quick replies everyone! I will look more into it asap.Pleasant
G
30

As you can see in ServerImpl, the default executor just "run" the task :

  157       private static class DefaultExecutor implements Executor {
  158           public void execute (Runnable task) {
  159               task.run();
  160           }
  161       }

you must provide a real executor for your httpServer, like that :

server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());

and your server will run in parallel. Carefull, this is a non-limited Executor, see Executors.newFixedThreadPool to limit the number of Thread.

Greenshank answered 6/2, 2013 at 13:8 Comment(6)
Thank you for the quick response. I will look more into executors and see if i can understand better :)Pleasant
Quick question though: does the executor replace the handler now in a sense or is something different?Pleasant
no, only the way to "serve" task. With a newCahdedThreadPool(), it will create as many thread as request. But your handler will be called as usual. Take care, if you reuse the same handler, he must be ThreadSafe.Greenshank
Looks like it works just fine with newFixedThreadPool, but i will need to study more about executors. Thanks a lot for the answer!Pleasant
@Greenshank Is this server synchronous or asynchronous ? As Http is a synchronous, I want to know how this server behaves.Tuba
@Hoysala the server is synchronous : he listen on port, accept the socket and start a new threadGreenshank
A
2

You used server.setExecutor(null) that runs the handler in the same caller thread. In this case, the main thread which runs the server.

You only need to change the line as

public static void main(String[] args) throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
    //Create the context for the server.
    server.createContext("/", new BaseHandler());
    server.setExecutor(Executors.newCachedThreadPool());
    server.start();
}
Afghan answered 25/2, 2019 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.