Servlet中的多线程安全问题
Servlet运行原理
Servlet中的多线程安全问题 演示
案例演示:
工程案例目录结构
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.study</groupId>
<artifactId>Servlet03</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
</dependency>
</dependencies>
</project>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name>Servlet04</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>suibian</servlet-name>
<servlet-class>web.SuibianServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>suibian</servlet-name>
<url-pattern>/suibian</url-pattern>
</servlet-mapping>
</web-app>
SuibianServlet.java
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SuibianServlet extends HttpServlet{
private double sal = 3000;
@Override
protected void service(HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
//涨工资
sal += 100;
//模拟网络延迟
try{
Thread.sleep(8000);
}catch(InterruptedException e){
e.printStackTrace();
}
//输出最新工资
res.setContentType("text/html;charset=utf-8");
PrintWriter pw = res.getWriter();
pw.println("<h1>工资:"+sal+"</h1>");
pw.close();
}
}
同时使用两个浏览器请求同一路径:http://localhost:8080/Servlet04/suibian;会发现最终显示效果如下:
与我们希望的3100,3200不符。
IE:
Chrome:
添加线程锁后:
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SuibianServlet extends HttpServlet{
private double sal = 3000;
@Override
protected void service(HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
synchronized(this){
//涨工资
sal += 100;
//模拟网络延迟
try{
Thread.sleep(8000);
}catch(InterruptedException e){
e.printStackTrace();
}
//输出最新工资
res.setContentType("text/html;charset=utf-8");
PrintWriter pw = res.getWriter();
pw.println("<h1>工资:"+sal+"</h1>");
pw.close();
}
}
}
同时使用两个浏览器请求同一路径:http://localhost:8080/Servlet04/suibian;会发现最终显示效果如下:
与我们希望的3100,3200相符合。线程安全解决。
IE:
Chrome: