异步处理

Servlet3.0提供异步处理

  在以前的Servlet规范化,如果Servlet作为控制器调用了一个耗时的业务方法,那么必须等到业务方法完全返回之后才能生成响应,这将使用Servlet对业务方法的调用变成一种阻塞式的调用,因此效率比较低。

  Servlet3.0规范引入了异步处理来解决这个问题,异步处理允许Servlet重新发起一条新线程去调用 耗时业务方法,这样就可以避免等待。
Servlet3.0的异步处理是通过AsyncContext类来处理的,Servlet可通过ServletRequest的如下两个方法开启异步调用,创建AsyncContext对象:

AsyncContext startAsync()

AsyncContext startAsync(ServletRequest,ServletResponse)

 

异步处理类AsyncServlet.java

package aniyo.servlet.async;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

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;

/**
 * Servlet 3.0提供的异步处理
 * 异步操作通过AsyncContext类来处理,通过startAsync()方法来开启异步调用
 * @author aniyo
 * blog:http://aniyo.iteye.com
 *
 */
@WebServlet(name="asyncServle",urlPatterns="/asyncServlet",asyncSupported=true)
public class AsyncServlet extends HttpServlet {

    /* (non-Javadoc)
     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=GBK");
        PrintWriter out = response.getWriter();
        out.println("<title>异步调用示例</title>");
        out.println("进入Servlet的时间:"+new Date()+".<br/>");
        out.flush();
        //创建AsyncContext,开始异步调用
        AsyncContext actx = request.startAsync();
        //设置异步调用的超时时长
        actx.setTimeout(30*1000);
        //启动异步调用的线程
        actx.start(new Executor(actx));
        out.println("结束Servlet的时间:"+new Date()+".<br/>");
        out.flush();
    }
}

 

线程类Executor.java

package aniyo.servlet.async;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.AsyncContext;
import javax.servlet.ServletRequest;

public class Executor implements Runnable{
    private AsyncContext actx = null;

    public Executor(AsyncContext actx) {
        this.actx = actx;
    }

    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {

        //等待5秒
        try {
            Thread.sleep(5*1000);
            ServletRequest request = actx.getRequest();
            List<String> books = new ArrayList<String>();
            books.add("java");
            books.add("oracle");
            books.add("j2ee");
            request.setAttribute("books", books);
            actx.dispatch("/async.jsp");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

async.jsp

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" session="false"%>
    <%@ taglib prefix = "c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<ul>
    <c:forEach items="${books}" var="book">
        <li>
            ${book }
        </li>
    </c:forEach>
</ul>
<%out.println("业务调用结束的时间:"+ new Date());
    //完成异步调用
    //request.getAsyncContext().complete();
%>
</body>
</html>
时间: 2024-07-28 21:14:29

异步处理的相关文章

Windows 8应用开发之异步调用

 不论是桌面客户端还是Web应用通常会出现处理时间较长的操作,为了在这段时间内不影响用户与应用之间的交互体验,开发人员通常会使用异步调用技术,使得比较复杂的逻辑操作由异步进行,用户仍然可以继续使用应用,不会有无响应的等待情况出现. 本篇将通过一个简单的实例演示如何在Windows 8 应用中使用异步编程.首先我们来编写一个"Get Blogs"按钮,点击它可以从Windows Blog中获取博客列表.当然获取博客信息的过程是由异步进行的,这个过程中为了测试用户仍然可以与应用交互,我们再

python的分布式任务huey如何实现异步化任务讲解

 本文我们来分享一个python的轻型的任务队列程序,他可以让python的分布式任务huey实现异步化任务,感兴趣的朋友可以看看.     一个轻型的任务队列,功能和相关的broker没有celery强大,重在轻型,而且代码读起来也比较的简单.  关于huey的介绍:  (比celery轻型,比mrq.rq要好用 !) a lightweight alternative.     written in python     no deps outside stdlib, except redi

如何使用ASP脚本制作异步装载的树形结构(一)

脚本|异步 树形结构是描述层次数据的常见方法.本文介绍的树形结构生成程序主要由一个ASP页面.二个JavaScript函数构成.该树形结构是异步的,也就是说,节点数据仅在必要时才读取,而不是一次性全部发送到客户端. 一.概述 树形结构中所有的节点都必须包含以下属性:本身的ID,父节点的ID,以及本节点的说明(节点文本).本文用到了一个Access数据库Tree.mdb来保存这些节点信息.Tree.mdb包含表tblTree,其定义如下: 字段名称 类型 说明 ElementID 自动编号 节点的

异步上传UploadFileAsync老是提示有无效参数,错在哪里

问题描述 异步上传UploadFileAsync老是提示有无效参数,错在哪里 错在哪里 ???文件明明是存在的 解决方案 第一个参数不对,应该放在new Uri()里面. 解决方案二: 第一个参数是Uri,你传递string当然错了 c.UploadFileAsync(new Uri(""http://localhost:.................."")POST"".........."")

关于支付系统中的同步通知和异步通知电商的区别,为什么需要通知

问题描述 关于支付系统中的同步通知和异步通知电商的区别,为什么需要通知 在电商对应的支付系统中当支付完成之后需要做相关的同步通知和异步通知操作,请大神解释一下什么是同步通知和异步通知,为什么需要同步通知和异步通知. 解决方案 同步用于即时通知支付完成 异步用于防止信息漏发漏收 解决方案二: 可以这样理解, 1.用户(买家)支付完成后,电商平台需要实时的给用户一个通知,如支付已经处理等待订单确认. 2.电商平台,这块就需要考虑系统技术方面的各个环节,考虑应对复杂多变的并发用户量.业务.流量.网络环

分享一个异步任务在遇到IO异常时支持递归回调的辅助方法

public void TryAsyncActionRecursively<TAsyncResult>( string asyncActionName, Func<Task<TAsyncResult>> asyncAction, Action<int> mainAction, Action<TAsyncResult> successAction, Func<string> getContextInfoFunc, Action<E

再谈IO的异步,同步,阻塞和非阻塞

原本转过一个<六种Socket I/O模型幽默讲解>,里面用比喻的方法讲解各种IO,但说到底那个时候我对同步异步这些还是只知其表.还未能完全理解异步和同步,现在觉得清晰一些了.总结一下. 前提概要: IO的过程: 整个IO的过程其实是应用发起IO的请求,到应用获取到IO请求数据的中间过程. 这个中间,其实主要的时间就是系统准备数据的过程.这也是异步技术的优化所在. 对系统调用的理解: 首先,我们要明确一点.IO的操作属于一种系统调用.也就是应用在运行中,进入到内核代码来执行某些重要的操作. 其

ODBC中的同步与异步执行模式

1.引言 近年来,随着计算机局域网技术的不断发展,计算机体系结构已经发展到复杂而开放的客户机/服务器模式.对于客户机/服务器应用的开发,现在常用的前端开发工具有:VisualBasic.Delphi.PowerBuilder等.它们可通过ODBC接口访问服务器的SQLServer数据库服务器. VisualBasic.Delphi.PowerBuilder等开发工具在使用ODBC2.0来编写程序时,通常会提供三种方法来进行数据库应用程序的方案设计: ·使用数据控制项 ·使用数据库对象变量进行编程

关于异步任务设计的几点思考

为什么需要异步任务 手机上的CPU和内存等资源是有限的. android应用有一个主线程常用于界面的更新.如果所有事情(包括耗时操作,IO操作,网络操作)都在主线程进行,可能因为系统无法及时处理而导致界面卡顿,甚至ANR. 为了避免ANR,解决卡顿问题,提高应用操作流畅性,我们需要把(耗时操作,IO操作,网络操作)等耗时/耗资源的操作放到异步的子线程中进行. ANR超时时间在ActivityManagerService.java文件中进行了定义 1.前台broadcast超时时间为10秒,后台b

异步调用Web服务方法

基于Ajax技术构建的门户是web 2.0这一代中最为成功的Web应用程序.而这块市场上iGoogle和Pageflakes这两大站点已经走在了时代的前列. 当你打开Pageflakes,将会看到如下的界面: 接下来就是界面上的各个"部件"去向服务器请求各种web服务,而服务器作为代理,则代为向外部web服务发出请求.(这是因为ajax调用无法跨越,所以常通过代理来请求数据) 问题场景:某个很受用户欢迎的"部件"很长时间不能执行,导致很对请求无法及时执行,引起请求失