2015-05-01 79 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