Servlet基础(三) Servlet的多线程同步问题
Servlet基础(三) Servlet的多线程同步问题
Servlet/JSP技术和ASP、PHP等相比,由于其多线程运行而具有很高的执行效率。
由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的同步问题。
如果在编写Servlet/JSP程序时不注意到多线程的同步问题,这往往造成程序在少量用户访问时没有任何问题,而在并发用户上升到一定值时,就会经常出现一些莫名其妙的问题,对于这类随机性的问题调试难度也很大。
比如下面这个程序就有问题。
存在多线程问题的程序例子
这个例子中,首先有一个JSP页面,其中有一个简单的表单:
<form action="MultiThreadServlet">
<input type="text" name="username">
<input type="submit" value="submit">
</form>
提交表单后,转向一个Servlet进行处理:
获取请求中的参数,并且调用setAttribute方法将其值存储,转向下一个jsp页面:
package com.shengqishiwind.servlet; 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 MultiThreadServlet extends HttpServlet
{
//使用成员变量
private String username; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//从请求中得到参数,即用户名
username = request.getParameter("username"); //得到当前线程的名字
System.out.println("Thread Name: " + Thread.currentThread().getName()); //模拟一些后端的业务处理
try
{ Thread.sleep(10000);
}
catch (Exception e)
{
e.printStackTrace();
} request.setAttribute("username", username);
//请求转发
request.getRequestDispatcher("hello.jsp").forward(request, response); } }
中间让线程停留了10秒钟,来模拟一些操作。
在下一个JSP页面中将该值显示出来:
<body>
username: <%= request.getAttribute("username")%>
</body>
这样做有什么问题呢?
打开浏览器,输入访问地址后,输入一个用户名zhangsan,再打开一个窗口,输入用户名lisi。
两个浏览器窗口都提交以后,过了一定时间,可以看到两边返回值都是lisi。
问题原因
Servlet的多线程同步问题:
Servlet本身是单实例的,这样当有多个用户同时访问某个Servlet时,会访问该唯一的Servlet实例中的成员变量,如果对成员变量进行写入操作,那就会导致Servlet的多线程问题,即数据不一致。
解决同步问题的方案
1.解决Servlet多线程同步问题的最好方式:
去除实例变量,使用局部变量。
比如上面那个例子修改如下:
public class MultiThreadServlet extends HttpServlet
{
//使用成员变量
//private String username; public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
//从请求中得到参数,即用户名
String username = request.getParameter("username"); //得到当前线程的名字
System.out.println("Thread Name: " + Thread.currentThread().getName()); //模拟一些后端的业务处理
try
{ Thread.sleep(10000);
}
catch (Exception e)
{
e.printStackTrace();
} request.setAttribute("username", username);
//请求转发
request.getRequestDispatcher("hello.jsp").forward(request, response); } }
不使用成员变量,而使用局部变量,因为局部变量在每个线程中都有各自的实例。
所以对Servlet来说,如果要对某个变量做写入操作,一定不要使用成员变量,而要使用局部变量。
2.使用同步代码块
synchronized{}
3.Servlet实现javax.serlvet.SingleThreadModel(Servlet2.4中已经废弃了该接口),此时Servlet容器将保证Servlet实例以单线程方式运行,也就是说,同一时刻,只会有一个线程执行Servlet的service()方法。
(这种方式了解一下就行了)。
参考资料
圣思园张龙老师Java Web视频教程。
Servlet基础(三) Servlet的多线程同步问题的更多相关文章
- Java第三阶段学习(十一、Servlet基础、servlet中的方法、servlet的配置、ServletContext对象)
一.Servlet简介 1.什么是servlet: sun公司提供的一套规范(接口),用来处理客户端请求.响应给浏览器的动态资源.但servlet的实质就是java代码,通过java的API动态的向 ...
- servlet多线程同步问题
Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率.•由于Servlet/JSP默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的同步问题.•如 ...
- 2 Servlet基础
作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) 1. 从浏览器访问Servlet的流程 刚才发现,这里的图片不能正常显示,所以我给个链接,大家可以下载下来看从浏 ...
- Java之JSP和Servlet基础知识
JSP基础 JSP起源 JSP,JavaServer Pager的简称.由SUN倡导并联合其它公司创建. JSP是一门脚本语言 JSP可以嵌入到HTML中 JSP拥有Java语言的所有特性 面向对象. ...
- J2EE基础之Servlet
J2EE基础之Servlet 1. 什么是Servlet? Servlet即Java服务小程序,是使用应用程序设计接口以及相关类和方法的Java程序.它可以作为一种插件,像Applet程序一样嵌入到 ...
- JSP数据交互(二)和Servlet基础
01.Application原理与应用 01.application对象的作用域范围是整个应用服务,而它在应用中所承担的责任就类似于一个全局变量.只要服务启动,则application对象就会存在. ...
- Servlet基础(一) Servlet简介 关键API介绍及结合源码讲解
Servlet基础(一) Servlet基础和关键的API介绍 Servlet简介 Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中. Servlet容器负责Servl ...
- JavaWeb学习之Servlet(三)----Servlet的映射匹配问题、线程安全问题
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140529.html 一.Servlet映射匹配问题: 在第一篇文章中的 ...
- JSP/Servlet基础语法
相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp ...
随机推荐
- 数据结构 - Codeforces Round #353 (Div. 2) D. Tree Construction
Tree Construction Problem's Link ------------------------------------------------------------------- ...
- 使用WebKit.net加载HTML编辑器
关于webkit.net使用请看这里http://www.cnblogs.com/linyijia/p/4045333.html nicedit编辑器请到这里下载http://www.nicedit. ...
- Mac下JDK安装配置
首先可以通过官网下载JDK:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html,至于下什么版本根 ...
- JS表单验证插件(支持Ajax验证)
自己编写了一个表单验证插件,支持ajax验证,使用起来很简单. 每个需要验证的表单元素下面有一个span标签,这个标签的class有一个valid表示需要验证,如果有nullable则表示可为空:ru ...
- PHP条件语句语法与示例
一.if…else语句 语法: 1 if(条件){ …… } else{ …… } 2 if(条件){ …… } elseif(条件){ …… } else{ …… } 示例1: <?php & ...
- 控制器描述者(ControllerDescriptor),行为方法描述者(ActionDescriptor),参数描述者(ParameterDescriptor)的小结
Model的绑定是在Action方法绑定参数时发生的,这个绑定的参数过程要用到的元数据来自于控制器,行为方法和参数的描述者ContrllerDescriptor,ActionDescriptor和Pa ...
- SEO技巧汇集
每个人都喜欢好用的技巧,对吗?这里有55个用于搜索引擎优化的小技巧,甚至你的老妈用起来都易如反掌.哦,不是我的老妈,但你明白我的意思.这意味着网页设计师和SEO新手中大部分人都能迅速上手,没有任何困难 ...
- php.ini 配置详细选项
php.ini 或 php3.ini 是 PHP 在启动时会读取的配置文件.该文件的存放路径为 /usr/local/lib/.在 PHP 3.x 版的配置文件为 php3.ini:而在 PHP 4. ...
- java一点小的知识点
1.在dos底下编译运行java文件时,若有包名,需要建立包名对应的文件夹,然后编译的时候写出包名:java.mypack.PackageDemo 2.代码中有包名的时候,自动创建文件夹并编译的方法: ...
- [函数] Firemonkey 取得 Windows 目前 User 的 Desktop 目录
下列方法仅提供 Windows 平台使用,所以需要使用编译开关,代码如下: uses {$IFDEF MSWINDOWS} Winapi.Windows, Winapi.SHFolder, {$END ...