Sarkhan
Sarkhan

Reputation: 1291

Asynchronous Process in Servlet

I'd like to wait requests 10 secs per each request but requests don't must wait each other.so second request doesn't must wait 20 seconds.

My Servlet:

    @WebServlet(value = "/account", asyncSupported = true)
    public class AccountServlet extends javax.servlet.http.HttpServlet {

        public AccountServlet() {

        }

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) {
            AsyncContext ac = request.startAsync();

            ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
            executor.execute(new MyAsyncService(ac));
        }

        @Override
        public void init(ServletConfig config) throws ServletException {

        }
    }

My asynchronous process class:

    class MyAsyncService implements Runnable {

        AsyncContext ac;

        public MyAsyncService(AsyncContext ac) {
            this.ac = ac;
        }

        @Override
        public void run() {
            try {
                System.out.println("started");
                Thread.sleep(10000);
                System.out.println("completed");
                ac.complete();
            } catch (InterruptedException ex) {
                Logger.getLogger(MyAsyncService.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Upvotes: 0

Views: 413

Answers (1)

Piotrek Bzdyl
Piotrek Bzdyl

Reputation: 13175

It would be more optimal to schedule the completion of the request without blocking a thread. Below is your code modified to do that (using Java 8 lambdas).

@WebServlet(value = "/account", asyncSupported = true)
public class AccountServlet extends javax.servlet.http.HttpServlet {
    private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext ac = request.startAsync();
        executor.schedule(ac::complete, 10, TimeUnit.SECONDS);
    }

    @Override
    public void destroy() {
        executor.shutdown();
    }
}

Note that depending on your runtime environment (i.e. container) you might not be allowed to create your own executor and might need to use one provided by EE container.

Upvotes: 1

Related Questions