0 0

Servlet3中的AsyncContext异步和多线程异步有什么区别5

我如果想异步向页面输出,则可以使用Servlet3中的AsyncContext。也可以在Servlet中另外启动一个多线程处理,让主线程先返回页面

两种方式的代码如下

public class ListServlet extends HttpServlet 
{
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException 
    {
        response.getWriter().println("I am begin output !");
        response.getWriter().flush();
         
        //方式一
        AsyncContext async = request.startAsync();
        new AsyncOutput(async).start();
         
        //方式二
        new ThreadOutput(response).start();
         
        response.getWriter().println("I am finash output !");
        response.getWriter().flush();
    }
 
}
 
class AsyncOutput extends Thread
{
    private AsyncContext async;
    public AsyncOutput(AsyncContext async)
    {
        this.async = async;
    }
    public void run() 
    {
        try
        {
            Thread.sleep(3000);
            async.getResponse().getWriter().println("I was three minutes late !");
            async.getResponse().getWriter().flush();
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}
 
class ThreadOutput extends Thread
{
    private HttpServletResponse response;
    public ThreadOutput(HttpServletResponse response)
    {
        this.response = response;
    }
    public void run() 
    {
        try
        {
            Thread.sleep(3000);
            response.getWriter().println("I was three minutes late !");
            response.getWriter().flush();
        }catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}


这两种效果是一样啊

既然如此,那还搞什么AsyncContext

AsyncContext有什么不一样的地方

以上两种使用方式,有什么区别?

求指点
2014年5月12日 16:14

3个答案 按时间排序 按投票排序

0 0

采纳的答案

AsyncContext不是让你异步输出,而是让你同步输出,但是解放服务器端的线程使用,使用AsyncContext的时候,对于浏览器来说,他们是同步在等待输出的,但是对于服务器端来说,处理此请求的线程并没有卡在那里等待,则是把当前的处理转为线程池处理了,关键就在于线程池,服务器端会起一个线程池去服务那些需要异步处理的请求,而如果你自己每次请求去起一个线程处理的话,这就有可能会耗大量的线程。

你目前对AsyncContext 的使用并不是最佳实践,实际上应该这样使用:

final AsyncContext asyncContext = request.getAsyncContext();
            asyncContext.addListener(new AsyncListener() {
                @Override
                public void onComplete(AsyncEvent event) throws IOException {
                    //在这里处理正常结束的逻辑
                }

                @Override
                public void onTimeout(AsyncEvent event) throws IOException {
                    //在这里处理超时的逻辑
                }

                @Override
                public void onError(AsyncEvent event) throws IOException {
                    //在这里处理出错的逻辑
                }

                @Override
                public void onStartAsync(AsyncEvent event) throws IOException {
                    //在这里处理开始异步线程的逻辑
                }
            });
            //设置超时的时间,到了时间以后,会回调onTimeout的方法
            asyncContext.setTimeout(10000L);
            //在这里启动,传入一个Runnable对象,服务器会把此Runnable对象放在线程池里面执行
            asyncContext.start(new Runnable() {
                @Override
                public void run() {
                    //在这里做耗时的操作,如果做完,则调用complete方法通知回调,异步处理结束了
                    asyncContext.complete();
                }
            });

2014年5月12日 18:10
0 0

我们可以在容器内部配置一些异步超时时间关于AsyncContext的配置,以超时为例,当异步线程中的数据在向response中写的时候,如果已经超时,此时的数据就写不回去了。而通过线程持有response的方式,其实就相当于组合使用了response一样,异步Context的一切其它配置,都不会影响之。我想这应该是两者的区别吧。

2014年5月12日 18:17
0 0

上面的排版太难看了,看这个:

final AsyncContext asyncContext = request.getAsyncContext();
//添加监听器监听异步的执行结果
asyncContext.addListener(new AsyncListener() {
    @Override
    public void onComplete(AsyncEvent event) throws IOException {
        //在这里处理正常结束的逻辑
    }

    @Override
    public void onTimeout(AsyncEvent event) throws IOException {
        //在这里处理超时的逻辑
    }

    @Override
    public void onError(AsyncEvent event) throws IOException {
        //在这里处理出错的逻辑
    }

    @Override
    public void onStartAsync(AsyncEvent event) throws IOException {
        //在这里处理开始异步线程的逻辑
    }
});
//设置超时的时间,到了时间以后,会回调onTimeout的方法
asyncContext.setTimeout(10000L);
//在这里启动,传入一个Runnable对象,服务器会把此Runnable对象放在线程池里面执行
asyncContext.start(new Runnable() {
    @Override
    public void run() {
        //在这里做耗时的操作,如果做完,则调用complete方法通知回调,异步处理结束了
        asyncContext.complete();
    }
});

2014年5月12日 18:11

相关推荐

    异步servlet

    异步Servlet是Java Servlet API的一个重要特性,它允许在Servlet容器中执行异步处理,显著提高了Web应用程序的性能和响应性。在传统的Servlet中,请求处理是同步的,即Servlet容器接收请求,调用Servlet的service...

    Servlet3.0新特性,Servlet3新特性,Servlet3注解,Servlet3异步处理【蕃薯耀】

    而在Servlet3.0中,可以通过`AsyncContext` API来实现异步处理,将请求处理逻辑从主线程分离出来,释放主线程处理其他请求。这样可以提高服务器的吞吐量和响应时间,尤其是处理长时间运行的任务时。 ```java @...

    servlet多线程

    4. **避免在Servlet中创建额外线程**:由于Servlet本身已具备多线程特性,额外创建线程可能会引入复杂的线程安全问题,除非有特殊需求。 5. **对外部资源的线程安全操作**:在多个Servlet中对同一外部资源(如文件...

    tomcat中多线程对于servlet处理的4篇资料

    在Java Web开发中,Tomcat是一个广泛...综上所述,理解Tomcat中的多线程处理对于优化Servlet性能和解决潜在的并发问题至关重要。通过对线程池的配置和使用最佳实践,开发者可以有效地提高Web应用的响应速度和可伸缩性。

    java实现多文件异步上传

    ### Java实现多文件异步上传知识点详解 在现代Web应用开发中,文件上传是一个非常常见的需求,尤其是在涉及图片、文档等多媒体数据的应用场景下。为了提高用户体验,异步上传技术得到了广泛的应用。本文将深入探讨...

    Servlet3-sources-code

    这提高了服务器处理高并发的能力,避免了传统的多线程模型中线程池资源的浪费。通过`ServletRequest.startAsync()`方法,开发者可以启动一个异步上下文,并在后续时间点调用`AsyncContext.complete()`来结束处理。 ...

    servlet3 api 文档

    Servlet3.1引入了异步处理能力,通过`AsyncContext`接口,开发者可以在后台线程中执行耗时的操作,而不会阻塞主线程,从而提高了Web应用的性能和响应速度。这使得处理大量I/O操作或者长时间运行的任务成为可能,而...

    异步servlet上传文件,解决网速慢以及大文件,耗完线程问题

    假如一个场景,用户上传文件,某些用户网速较慢,同时存在100个这样的用户,如果BIO且最大线程设为100会导致线程用完。...本实例采用tomcat8作为容器,开启异步servlet读写事件,解决高并发IO传输问题。

    1工作临时-servlet 多线程问题

    标题 "1工作临时-servlet 多线程问题" 暗示了我们在讨论Servlet在处理多线程环境下的挑战和解决方案。Servlet是Java Web开发中用于处理HTTP请求的服务端组件,常常需要处理并发请求,因此多线程是其核心特性之一。 ...

    servlet是如何同时处理多个请求的

    - `HttpServletRequest`和`HttpServletResponse`对象是线程局部的,每个请求都会获得新的对象实例,因此它们在多线程环境中是安全的。开发者可以在`service`方法中放心地使用这两个对象。 7. **异步Servlet**: -...

    javaweb异步处理程序

    在此期间,服务器可以释放线程去处理其他请求,而Servlet可以在稍后某个时间点完成异步操作,通过`AsyncContext`对象的`complete()`方法结束异步处理并发送响应。 在实际应用中,JavaWeb异步处理常用于处理耗时的...

    test-servlet3-without-webxml.rar

    - **异步处理**:Servlet 3.0支持异步处理,通过`AsyncContext`接口,可以将请求处理工作交给后台线程,提高系统响应速度。 - **微容器(Microcontainer)**:Servlet 3.0允许在应用程序内部创建微型容器,使得...

    Servlet3.1规范(最终版)

    Servlet3.1引入了异步处理能力,允许开发者在Servlet容器内部创建异步上下文(AsyncContext),从而将控制权交还给容器,避免了线程阻塞。这种方式使得服务器可以处理更多的并发请求,提高系统吞吐量。开发者可以在...

    ORACLE官方培训servlet-3新特性中文版

    - 通过实现`AsyncContext`接口,Servlet可以在等待外部资源时释放线程资源,提高服务器的并发处理能力。 #### 三、结论 综上所述,Servlet 3.0的新特性大大提升了Web应用的开发效率和性能表现。通过简化部署、...

    Servlet API 中文参考 chm版.rar

    9. **多线程与并发**: Servlet默认在单线程环境中运行,但可以通过覆盖`getThreadLocalRequest()`和`getThreadLocalResponse()`方法实现线程安全。注意,多个请求可能会同时访问同一个Servlet实例,因此必须考虑线程...

    Servlet3.1规范(最终版).中文

    综上所述,Servlet3.1规范通过提供异步处理、注解驱动的配置、WebSocket支持和更多的安全特性,极大地提升了Java Web开发的效率和灵活性。这一版本的Servlet规范旨在简化开发流程,同时保持向后兼容性,使开发者能够...

    Springboot Druid多数据源 多线程

    总结起来,这个项目展示了如何利用Spring Boot和Druid实现多数据源切换,以及如何在Spring Boot中配置和使用多线程来提升数据库操作的并发性能。对于初学者,这是一个很好的学习资源,可以深入理解Spring Boot的自动...

Global site tag (gtag.js) - Google Analytics