|
package com.servlet3.demo; |
|
|
|
import java.io.IOException; |
|
import java.io.PrintWriter; |
|
import java.util.concurrent.ExecutionException; |
|
import java.util.concurrent.ExecutorService; |
|
import java.util.concurrent.Executors; |
|
import java.util.concurrent.Future; |
|
import java.util.concurrent.ThreadFactory; |
|
import java.util.concurrent.ThreadPoolExecutor; |
|
import java.util.concurrent.TimeUnit; |
|
import java.util.concurrent.TimeoutException; |
|
|
|
import javax.servlet.ServletException; |
|
import javax.servlet.annotation.WebServlet; |
|
import javax.servlet.http.HttpServlet; |
|
import javax.servlet.http.HttpServletRequest; |
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
/** |
|
* Servlet中添加异步支持 |
|
* |
|
* @author yongboy |
|
* @time 2012-1-17 |
|
* @version 1.0 |
|
*/ |
|
@WebServlet(urlPatterns = "/async3") |
|
public class DemoAsync3Action extends HttpServlet { |
|
private static final long serialVersionUID = 1L; |
|
private final ExecutorService executor; |
|
|
|
{ |
|
executor = Executors.newCachedThreadPool(new ThreadFactory() { |
|
public Thread newThread(Runnable r) { |
|
Thread thread = new Thread(r); |
|
thread.setName("DemoAsyncAction3 executor Thread " |
|
+ thread.getId()); |
|
thread.setPriority(Thread.MAX_PRIORITY); |
|
|
|
return thread; |
|
} |
|
}); |
|
|
|
if (executor instanceof ThreadPoolExecutor) { |
|
// 不超过服务器CPU数目个线程较佳 |
|
((ThreadPoolExecutor) executor).setMaximumPoolSize(Runtime |
|
.getRuntime().availableProcessors()); |
|
} |
|
} |
|
|
|
protected void doGet(HttpServletRequest request, |
|
HttpServletResponse response) throws ServletException, IOException { |
|
// 添加此属性,告诉浏览器,需要分段显示 |
|
response.setHeader("Connection", "Keep-Alive"); |
|
response.setContentType("text/html;charset=UTF-8"); |
|
final PrintWriter out = response.getWriter(); |
|
|
|
output(out, "the manual async start ..."); |
|
|
|
Future<?> future = executor.submit(new Runnable() { |
|
@Override |
|
public void run() { |
|
try { |
|
// 假设实际业务耗时10秒 |
|
Thread.sleep(10000L); |
|
} catch (InterruptedException e) { |
|
e.printStackTrace(); |
|
} |
|
|
|
try { |
|
output(out, "the manual async goes here ..."); |
|
} catch (IOException e) { |
|
e.printStackTrace(); |
|
} |
|
} |
|
}); |
|
|
|
boolean result = false; |
|
try { |
|
// 在此处,会阻塞当前线程,直到超时或线程执行完毕... |
|
future.get(10L, TimeUnit.SECONDS); |
|
result = true; |
|
} catch (InterruptedException e) { |
|
e.printStackTrace(); |
|
} catch (ExecutionException e) { |
|
e.printStackTrace(); |
|
} catch (TimeoutException e) { |
|
e.printStackTrace(); |
|
} finally { |
|
future.cancel(true); |
|
} |
|
|
|
if (result) { |
|
output(out, "the manual async is ok ..."); |
|
} else { |
|
output(out, "the manual async is failure ..."); |
|
} |
|
|
|
// 按照顺序输出到此,结束请求 |
|
output(out, "the end of manual async ..."); |
|
out.close(); |
|
} |
|
|
|
private static void output(PrintWriter out, String message) |
|
throws IOException { |
|
out.println(message); |
|
out.flush(); |
|
} |
|
} |