关于Servlet的并发响应

本文通过实验验证了Servlet能够并发响应多个用户的访问请求。利用多线程机制,Servlet在一个实例上支持多个线程的同时访问,展示了如何通过代码实现这一过程。

关于Servlet的并发响应

 

http://blog.youkuaiyun.com/irelandken/article/details/6927713我们分析了Servlet的生命周期

Servlet的生命周期是这个Servlet被访问时构造,项目被Remove部署时才终止…

 

那么我们现在再来看看,当多个用户以doget/dopost方式同时访问同一个Servlet时,那个响应情况是怎么的呢??是一个一个来执行?还是多线程并行来执行呢??

 

1: 新建web Project

2:新建文件: Servlet_MutiThreads.java

 

 

[java]  view plain copy
  1. package myServlet;  
  2. import java.io.IOException;  
  3.    
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.    
  9.    
  10. public class Servlet_MutiThreads extends HttpServlet {  
  11.    
  12.     private static final long serialVersionUID = 1L;  
  13.    
  14.     @Override  
  15.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
  16.            throws ServletException, IOException {  
  17.         
  18.        System.out.println(Thread.currentThread().getName() + " is running");  
  19.         
  20.        try {  
  21.            Thread.sleep(10*1000);  
  22.        } catch (InterruptedException e) {  
  23.            e.printStackTrace();  
  24.        }  
  25.         
  26.        System.out.println(Thread.currentThread().getName() + " is ------------finished");  
  27.     }  
  28.    
  29.     @Override  
  30.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
  31.            throws ServletException, IOException {  
  32.         
  33.        doGet(req,resp);  
  34.     }  
  35.    
  36. }  
  37.    


3.XML加入:

[html]  view plain copy
  1.  <servlet>  
  2.   <servlet-name>Servlet_MutiThreads</servlet-name>  
  3.   <servlet-class>myServlet.Servlet_MutiThreads</servlet-class>  
  4. </servlet>  
  5.   
  6. <servlet-mapping>  
  7.   <servlet-name>Servlet_MutiThreads</servlet-name>  
  8.   <url-pattern>/myServlet/Servlet_MutiThreads</url-pattern>  
  9. </servlet-mapping>  


 

那么这个servlet的访问的url是: http://localhost:8080/Servlet_MutiThreads//myServlet/Servlet_MutiThreads

 

这个Servlet里,每次访问都sleep 10s,就是说每个访问的持续时间为10s….(这里为不什么不用wait呢? 是因为sleep时,尽管线程休眠了,但还是不会释放锁的,而这正是我们想要的,而wait是会释放的)

 

 

我们有在地址栏里多次访问这个URL(连续按多次enter):

 

 

我们可以看到,这个访问是并发的,并Servlet的响应也是并发的,查看资料:

 

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。

 

当客户端第一次请求某个Servlet时,Servlet 容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。

 

Servlet容器会自动使用线程池等技术来支持系统的运行

 

我们就验证了Servlet能并发响应多个用户的访问

在 Java 并发编程中,Servlet 的处理机制与线程安全密切相关,尤其是在高并发环境下。以下是对 Java Servlet 并发处理机制及其线程安全与优化的详细说明。 ### Servlet并发处理机制 Servlet 容器(如 Tomcat)使用线程池来管理并发请求的处理。当客户端发送请求时,容器从线程池中选择一个空闲线程来执行 Servlet 的 `service` 方法。如果线程池中的线程全部被占用,新请求将被放入队列中等待处理,或者根据配置拒绝服务[^4]。 这种机制使得多个请求可以并行处理,从而提高系统吞吐量。然而,由于多个线程可能同时访问同一个 Servlet 实例,因此线程安全性成为关键问题[^1]。 ### 线程安全问题的来源 Servlet 实例是单例的,这意味着多个线程共享同一个实例。如果 Servlet 中包含成员变量,并且这些变量被多个线程同时修改,就可能导致数据不一致或其他并发问题[^5]。 例如,以下代码中的 `counter` 变量在并发环境下可能会导致不一致: ```java public class CounterServlet extends HttpServlet { private int counter = 0; protected void doGet(HttpServletRequest req, HttpServletResponse res) { counter++; // ... } } ``` ### 保证线程安全的方法 为了确保 Servlet 的线程安全,可以采用以下几种方法: 1. **避免使用成员变量**:尽量将变量定义在方法内部,这样每个线程都会有自己独立的变量副本。 2. **使用同步机制**:可以通过 `synchronized` 关键字或 `ReentrantLock` 来保护共享资源的访问。 3. **使用线程安全的类**:例如 `java.util.concurrent` 包中的并发集合类。 4. **无状态设计**:设计无状态的 Servlet,不依赖于成员变量,所有状态信息都存储在请求或会话中。 ### 优化并发性能 除了确保线程安全外,还可以通过以下方式优化 Servlet并发性能: - **异步处理**:使用异步 Servlet 技术,释放工作线程回池,以便处理更多新请求,尤其是在等待数据库响应等阻塞操作时减少线程浪费[^2]。 - **合理配置线程池**:根据应用的实际需求调整线程池的大小和队列容量,以平衡资源利用和响应时间。 - **减少同步块的范围**:尽量缩小同步代码块的范围,以减少线程竞争和提高并发性能。 ### 示例代码 以下是一个使用 `synchronized` 关键字保护共享资源的示例: ```java public class CounterServlet extends HttpServlet { private int counter = 0; protected void doGet(HttpServletRequest req, HttpServletResponse res) { synchronized (this) { counter++; } // ... } } ``` 在这个例子中,`synchronized` 块确保了 `counter` 变量的原子性和可见性,从而避免了并发问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值