比赛网站开发wordpress 路由怎么配
web/
2025/10/8 22:37:11/
文章来源:
比赛网站开发,wordpress 路由怎么配,j2ee网站开发买什么书,免费申请注册网站servlet3异步在深入了解什么是异步Servlet之前#xff0c;让我们尝试了解为什么需要它。 假设我们有一个Servlet#xff0c;处理时间很长#xff0c;如下所示。 LongRunningServlet.java package com.journaldev.servlet;import java.io.IOException;
import java.io.Prin… servlet3异步 在深入了解什么是异步Servlet之前让我们尝试了解为什么需要它。 假设我们有一个Servlet处理时间很长如下所示。 LongRunningServlet.java package com.journaldev.servlet;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;WebServlet(/LongRunningServlet)
public class LongRunningServlet extends HttpServlet {private static final long serialVersionUID 1L;protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {long startTime System.currentTimeMillis();System.out.println(LongRunningServlet Start::Name Thread.currentThread().getName() ::ID Thread.currentThread().getId());String time request.getParameter(time);int secs Integer.valueOf(time);// max 10 secondsif (secs 10000)secs 10000;longProcessing(secs);PrintWriter out response.getWriter();long endTime System.currentTimeMillis();out.write(Processing done for secs milliseconds!!);System.out.println(LongRunningServlet Start::Name Thread.currentThread().getName() ::ID Thread.currentThread().getId() ::Time Taken (endTime - startTime) ms.);}private void longProcessing(int secs) {// wait for given time before finishingtry {Thread.sleep(secs);} catch (InterruptedException e) {e.printStackTrace();}}} 如果我们通过浏览器在URL上方为http://localhost:8080/AsyncServletExample/LongRunningServlet?time8000 servlet上方收到响应则响应为“处理完成8000毫秒” 8秒后。 现在如果您查看服务器日志将得到以下日志 LongRunningServlet Start::Namehttp-bio-8080-exec-34::ID103
LongRunningServlet Start::Namehttp-bio-8080-exec-34::ID103::Time Taken8002 ms. 因此尽管大多数处理与Servlet请求或响应无关但我们的Servlet线程运行了大约8秒。 这可能导致线程饥饿 -由于在所有处理完成之前我们的servlet线程被阻塞因此如果服务器收到大量要处理的请求它将达到最大servlet线程限制并且进一步的请求将出现Connection Refused错误。 在Servlet 3.0之前有针对这些长时间运行的线程的特定于容器的解决方案我们可以生成单独的工作线程来执行繁重的任务然后将响应返回给客户端。 启动工作线程后Servlet线程返回到Servlet池。 Tomcat的CometWebLogic的FutureResponseServlet和WebSphere的异步请求分派器是异步处理实现的一些示例。 特定于容器的解决方案的问题在于在不更改应用程序代码的情况下我们无法移至其他servlet容器这就是为什么在Servlet 3.0中添加了Async Servlet支持以为Servlet中的异步处理提供标准方式的原因。 异步Servlet实现 让我们看一下实现异步servlet的步骤然后为上述示例提供异步支持的servlet。 首先我们要提供异步支持的servlet应该具有WebServlet 批注 其asyncSupported值为true 。 由于实际工作将委托给另一个线程因此我们应该有一个线程池实现。 我们可以使用Executors框架创建线程池并使用servlet上下文侦听器来启动线程池。 我们需要通过ServletRequest.startAsync()方法获取AsyncContext的实例。 AsyncContext提供了获取ServletRequest和ServletResponse对象引用的方法。 它还提供了使用dispatch方法将请求转发到另一个资源的方法。 我们应该有一个Runnable实现 在这里我们将进行繁重的处理然后使用AsyncContext对象将请求分派到另一个资源或者使用ServletResponse对象写入响应。 处理完成后我们应调用AsyncContext.complete方法以使容器知道异步处理已完成。 我们可以将AsyncListener实现添加到AsyncContext对象中以实现回调方法–我们可以使用它为异步线程处理过程中发生错误或超时的情况提供对客户端的错误响应。 我们还可以在此处进行一些清理活动。 一旦我们完成了用于异步Servlet示例的项目它将如下图所示。 在Servlet上下文侦听器中初始化辅助线程池 AppContextListener.java package com.journaldev.servlet.async;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;WebListener
public class AppContextListener implements ServletContextListener {public void contextInitialized(ServletContextEvent servletContextEvent) {// create the thread poolThreadPoolExecutor executor new ThreadPoolExecutor(100, 200, 50000L,TimeUnit.MILLISECONDS, new ArrayBlockingQueueRunnable(100));servletContextEvent.getServletContext().setAttribute(executor,executor);}public void contextDestroyed(ServletContextEvent servletContextEvent) {ThreadPoolExecutor executor (ThreadPoolExecutor) servletContextEvent.getServletContext().getAttribute(executor);executor.shutdown();}} 该实现非常简单如果您不熟悉Executors框架请阅读Thread Pool Executor 。 有关监听器的更多详细信息请阅读Servlet Listener Tutorial 。 工作线程实现 AsyncRequestProcessor.java package com.journaldev.servlet.async;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.AsyncContext;public class AsyncRequestProcessor implements Runnable {private AsyncContext asyncContext;private int secs;public AsyncRequestProcessor() {}public AsyncRequestProcessor(AsyncContext asyncCtx, int secs) {this.asyncContext asyncCtx;this.secs secs;}Overridepublic void run() {System.out.println(Async Supported? asyncContext.getRequest().isAsyncSupported());longProcessing(secs);try {PrintWriter out asyncContext.getResponse().getWriter();out.write(Processing done for secs milliseconds!!);} catch (IOException e) {e.printStackTrace();}//complete the processingasyncContext.complete();}private void longProcessing(int secs) {// wait for given time before finishingtry {Thread.sleep(secs);} catch (InterruptedException e) {e.printStackTrace();}}
} 请注意AsyncContext的用法及其在获取请求和响应对象然后通过complete方法调用完成异步处理的用法。 AsyncListener实现 AppAsyncListener.java package com.journaldev.servlet.async;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebListener;WebListener
public class AppAsyncListener implements AsyncListener {Overridepublic void onComplete(AsyncEvent asyncEvent) throws IOException {System.out.println(AppAsyncListener onComplete);// we can do resource cleanup activity here}Overridepublic void onError(AsyncEvent asyncEvent) throws IOException {System.out.println(AppAsyncListener onError);//we can return error response to client}Overridepublic void onStartAsync(AsyncEvent asyncEvent) throws IOException {System.out.println(AppAsyncListener onStartAsync);//we can log the event here}Overridepublic void onTimeout(AsyncEvent asyncEvent) throws IOException {System.out.println(AppAsyncListener onTimeout);//we can send appropriate response to clientServletResponse response asyncEvent.getAsyncContext().getResponse();PrintWriter out response.getWriter();out.write(TimeOut Error in Processing);}} 注意onTimeout方法的实现在该方法中我们向客户端发送超时响应。 这是我们异步servlet的实现请注意使用AsyncContext和ThreadPoolExecutor进行处理。 AsyncLongRunningServlet.java package com.journaldev.servlet.async;import java.io.IOException;
import java.util.concurrent.ThreadPoolExecutor;import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;WebServlet(urlPatterns /AsyncLongRunningServlet, asyncSupported true)
public class AsyncLongRunningServlet extends HttpServlet {private static final long serialVersionUID 1L;protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {long startTime System.currentTimeMillis();System.out.println(AsyncLongRunningServlet Start::Name Thread.currentThread().getName() ::ID Thread.currentThread().getId());request.setAttribute(org.apache.catalina.ASYNC_SUPPORTED, true);String time request.getParameter(time);int secs Integer.valueOf(time);// max 10 secondsif (secs 10000)secs 10000;AsyncContext asyncCtx request.startAsync();asyncCtx.addListener(new AppAsyncListener());asyncCtx.setTimeout(9000);ThreadPoolExecutor executor (ThreadPoolExecutor) request.getServletContext().getAttribute(executor);executor.execute(new AsyncRequestProcessor(asyncCtx, secs));long endTime System.currentTimeMillis();System.out.println(AsyncLongRunningServlet End::Name Thread.currentThread().getName() ::ID Thread.currentThread().getId() ::Time Taken (endTime - startTime) ms.);}}运行异步Servlet 现在当我们在servlet上运行URL为http://localhost:8080/AsyncServletExample/AsyncLongRunningServlet?time8000我们得到的响应和日志如下 AsyncLongRunningServlet Start::Namehttp-bio-8080-exec-50::ID124
AsyncLongRunningServlet End::Namehttp-bio-8080-exec-50::ID124::Time Taken1 ms.
Async Supported? true
AppAsyncListener onComplete 如果我们将时间设置为9999则会发生超时并在客户端以“处理中的超时错误”和日志形式获得响应 AsyncLongRunningServlet Start::Namehttp-bio-8080-exec-44::ID117
AsyncLongRunningServlet End::Namehttp-bio-8080-exec-44::ID117::Time Taken1 ms.
Async Supported? true
AppAsyncListener onTimeout
AppAsyncListener onError
AppAsyncListener onComplete
Exception in thread pool-5-thread-6 java.lang.IllegalStateException: The request associated with the AsyncContext has already completed processing.at org.apache.catalina.core.AsyncContextImpl.check(AsyncContextImpl.java:439)at org.apache.catalina.core.AsyncContextImpl.getResponse(AsyncContextImpl.java:197)at com.journaldev.servlet.async.AsyncRequestProcessor.run(AsyncRequestProcessor.java:27)at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)at java.lang.Thread.run(Thread.java:680) 注意servlet线程快速完成了执行所有主要的处理工作都在其他线程中进行。 这就是异步Servlet的全部希望您喜欢它。 下载AsyncServletExample项目 参考 开发者食谱博客上来自JCG合作伙伴 Pankaj Kumar 的Servlet 3异步Servlet功能 。 翻译自: https://www.javacodegeeks.com/2013/08/async-servlet-feature-of-servlet-3.htmlservlet3异步
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/89301.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!