2015-05-01 55 views
-1

我想等待每个请求10秒的请求,但请求不必等待对方。所以第二个请求不必等待20秒。Servlet中的异步进程

我的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 { 

     } 
    } 

我的异步过程类:

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); 
      } 
     } 
    } 
+0

为什么投票能解释一下吗? – Sarkhan

回答

0

这将是更优的调度请求的完成而不会阻塞的线程。下面是修改后的代码(使用Java 8 lambda)。

@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(); 
    } 
} 

请注意,根据您的运行时环境(即容器),你可能不会被允许创建自己的遗嘱执行人,并可能需要使用一个由EE容器提供。

+0

我测试this.when我在同一浏览器中打开新标签每个选项卡等待eachother.i意味着第二个选项卡等待20秒而不是10秒。但是当我在其他浏览器测试每个浏览器等待10秒不等待eachother.Your code与我的代码相同 – Sarkhan

+0

您确定没有应用其他逻辑吗?例如过滤器增加了延迟?你是不是也调用你的'MyAsyncService'而不是仅仅调度执行器中的任务?您可以在'executor.schedule'之前和lambda内部(而不是仅仅调用ac :: complete)之前添加一些日志记录,并查看这些语句何时打印。 –

+0

我打开了新的应用程序,只需将一个servlet添加到应用程序中并粘贴您的代码即可。结果是每个选项卡都在等待其他人。您是否在测试您的代码? – Sarkhan