1. servlet默认是单例模式的,所以是单例多线程的。如果实现了singleservlet是可以多个servlet实例,下面是一个servlet的请求生命周期
    1. 1  

      客户端请求该 Servlet;
      加载 Servlet 类到内存;
      实例化并调用init()方法初始化该 Servlet;
      service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())。
      加载和实例化 Servlet。这项操作一般是动态执行的。然而,Server 通常会提供一个管理的选项,用于在 Server 启动时强制装载和初始化特定的 Servlet。
      Server 创建一个 Servlet的实例

      .然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法

    2. servlet可以是异步处理的,work线程立即返回,调用request.startAsync()获取到该请求对应的AsyncContext,然后调用AsyncContext的start()方法进行异步处理。但是另外一个线程池中又新增了一个线程,其中io操作还是会阻塞;
  2. servlet3.0和3.1

https://www.cnblogs.com/davenkin/p/async-servlet.html
在Servlet 3.0之前,Servlet采用Thread-Per-Request的方式处理请求,即每一次Http请求都由某一个线程从头到尾负责处理。如果一个请求需要进行IO操作,比如访问数据库、调用第三方服务接口等,那么其所对应的线程将同步地等待IO操作完成, 而IO操作是非常慢的,所以此时的线程并不能及时地释放回线程池以供后续使用,在并发量越来越大的情况下,这将带来严重的性能问题。即便是像Spring、Struts这样的高层框架也脱离不了这样的桎梏,因为他们都是建立在Servlet之上的。为了解决这样的问题,Servlet 3.0引入了异步处理,然后在Servlet 3.1中又引入了非阻塞IO来进一步增强异步处理的性能。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync(); asyncContext.start(() -> {
new LongRunningProcess().run();
try {
asyncContext.getResponse().getWriter().write("Hello World!");
} catch (IOException e) {
e.printStackTrace();
}
asyncContext.complete();
}); }

此时,我们先通过request.startAsync()获取到该请求对应的AsyncContext,然后调用AsyncContext的start()方法进行异步处理,处理完毕后需要调用complete()方法告知Servlet容器。start()方法会向Servlet容器另外申请一个新的线程(可以是从Servlet容器中已有的主线程池获取,也可以另外维护一个线程池,不同容器实现可能不一样),然后在这个新的线程中继续处理请求,而原先的线程将被回收到主线程池中。事实上,这种方式对性能的改进不大,因为如果新的线程和初始线程共享同一个线程池的话,相当于闲置下了一个线程,但同时又占用了另一个线程。

Servlet 3.0对请求的处理虽然是异步的,但是对InputStream和OutputStream的IO操作却依然是阻塞的,对于数据量大的请求体或者返回体,阻塞IO也将导致不必要的等待。因此在Servlet 3.1中引入了非阻塞IO(参考下图红框内容),通过在HttpServletRequest和HttpServletResponse中分别添加ReadListener和WriterListener方式,只有在IO数据满足一定条件时(比如数据准备好时),才进行后续的操作。

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
AsyncContext asyncContext = request.startAsync();
ServletInputStream inputStream = request.getInputStream();
inputStream.setReadListener(new ReadListener() {
@Override
public void onDataAvailable() throws IOException {
}
@Override
public void onAllDataRead() throws IOException {
executor.execute(() -> {
new LongRunningProcess().run();
try {
asyncContext.getResponse().getWriter().write("Hello World!");
} catch (IOException e) {
e.printStackTrace();
}
asyncContext.complete();
});
}
@Override
public void onError(Throwable t) {
asyncContext.complete();
}
});
}
}

最新文章

  1. Python+selenium自动化脚本编辑过程中遇到的问题和小技巧
  2. 解决asp.net(C#)中 DataTime 空值 null为0001-01-01
  3. iOS开发之UISearchBar初探
  4. Windows Store App 获取文件及文件夹列表
  5. ajax提交特殊字符的处理
  6. laravel named route
  7. [改善Java代码]线程优先级只使用三个等级
  8. swift入门-day01-基本语法
  9. iOS之UITableView带滑动操作菜单的Cell
  10. 可失败构造器(Failable Initializers)
  11. ExtJS中xtype 概览
  12. vue ajax返回html代码不渲染解决
  13. Java面试题之多线程打印
  14. Spring Boot JPA的Column Table 注解命名字段无效
  15. 重开Vue2.0
  16. Python开发——6.文件操作
  17. capjoint一些生成文件的解释
  18. Android创建和删除桌面快捷方式
  19. wc的使用
  20. 【python】Python3 循环语句

热门文章

  1. brand new start
  2. CSS精简工具——除去多余的css样式
  3. python中序列化模块json和pickle
  4. mysql与mysqli的区别
  5. RabbitMQ安装记录(windows10)
  6. Markdown使用方法
  7. spring中使用@PostConstruct和@PreConstruct注解
  8. R语言中的字符串处理函数
  9. Guava 3: 集合Collections
  10. Spark性能优化指南——高级篇