一,由于servlet是单实例的类,在每个新客户端访问时创建一个新的线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。
例:
1,使用一个简单的登陆页面提交用户名,密码
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>My JSP 'login.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body><h1>登陆</h1><hr><form action="test.do" name="loginform" method="post"><table><tr><td>用户名</td><td><input type="text" name="username"/></td></tr><tr><td>密码</td><td><input type="password" name="password"/></td></tr><tr><td colspan="2"><input type="submit" value="登陆"/></td></tr></table></form></body></html>
2,创建一个servlet文件
在servlet中创建两个全局变量用于接收用户名和密码
例:
package aaa;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 Ddd extends HttpServlet {/*** Constructor of the object.*/public Ddd() {super();}/*** Destruction of the servlet. <br>*/public void destroy() {super.destroy(); // Just puts "destroy" string in log// Put your code here }/*** The doGet method of the servlet. <br>** This method is called when a form has its tag value method equals to get.* * @param request the request send by the client to the server* @param response the response send by the server to the client* @throws ServletException if an error occurred* @throws IOException if an error occurred*/public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");out.println("<HTML>");out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");out.println(" <BODY>");out.print(" This is ");out.print(this.getClass());out.println(", using the GET method");out.println(" </BODY>");out.println("</HTML>");out.flush();out.close();}/*** The doPost method of the servlet. <br>** This method is called when a form has its tag value method equals to post.* * @param request the request send by the client to the server* @param response the response send by the server to the client* @throws ServletException if an error occurred* @throws IOException if an error occurred*/String Username;String Password;public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {Username=request.getParameter("username");Password=request.getParameter("password");Thread a=new Thread(){public void run(){try {//延迟4秒突出线程冲突Thread.sleep(4000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}};request.setAttribute("user", this.Password+""+this.Username);request.getRequestDispatcher("index.jsp").forward(request, response);}/*** Initialization of the servlet. <br>** @throws ServletException if an error occurs*/public void init() throws ServletException {// Put your code here }}
3,创建一个接收页面显示用户名和密码
例:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body><h1><%String a=(String)request.getAttribute("user");out.print(a);%></h1><br></body></html>
如果同时打开多个登陆页面进行登陆会造成servlet的线程冲突
3,解决方法:
可以通过解决java多线程的冲突的方式进行解决
synchronized(this){Username=request.getParameter("username");Password=request.getParameter("password");Thread a=new Thread(){public void run(){try {//延迟4秒突出线程冲突Thread.sleep(4000);} catch (InterruptedException e) {// TODO Auto-generated catch block e.printStackTrace();}}};}
通过在共享的代码块上锁解决