<%@ page contentType="text/html; charset=gb2312"%> 在Servlet和JSP中如何实现多线程安全?
网站公告:   ◆北天JAVA技术网热情为java爱好者服务,本网内容包括JAVA(JSP、servlet、EJB、webservice、j2ee、javabean、应用服务器、JavaScript),数据库(MYSQL、SQL Server、Sybase、Oracle、DB2、数据库综合知识),设计研究(设计模式、Struts、Spring、Hibernate、设计框架、设计综合知识),WEB2.0新技术(主要介绍AJAX),以及各种技术的入门、实例、例子等等,欢迎各位多来坐坐!◆  诚邀各位JAVA爱好者加盟!◆  本网站内容丰富,更新快,保证每周20篇以上!  
加入收藏
设为首页
联系站长
承接项目
  相关资源:网站首页 | 免费培训学院 | 技术论坛 | JAVA聊天室 | 作家专栏 | 开发工具 | 认证考试 | 会员俱乐部
  JAVA技术初学者园地 | jsp与servlet | javascript | Java源代码 | EJB | web service | 应用服务器 | JAVA综合知识
  设计研究设计模式 | 设计框架 | Struts | Spring | Hibernate | 开源项目 | 面向对象设计 | 设计综合知识
  数 据 库MYSQL | SQL Server | Sybase | Oracle | DB2 | Informix | Access | 数据库综合知识
  其他资源:AJAX新技术 | 网站开发 | ERP软件 | OA办公软件 | 商业智能BI | 开发综合知识 | 承接项目 | 项目试用

 
 
在Servlet和JSP中如何实现多线程安全?
     发布者: 发布时间:2007-07-11
Servlet的生命周期是由Web容器负责的,当客户端第一次请求Servlet时,容器负责初始化Servlet,也就是实例化这个Servlet类.以后这个实例就负责客户端的请求,一般不会再实例化其他Servlet类,也就是有多个线程在使用这个实例.Servlet之所以比CGI效率高就是因为Servlet是多线程的.如果该Servlet被声明为单线程模型的话,容器就会维护一个实例池,那么将存在多个实例.

2.Servlet的线程安全

Servlet规范已经声明Servlet不是线程安全的,所以在开发Servlet的时候要注要这个问题.这里以一个现实的模型来说明问题,先定义一个Servlet类,再定义一个SmulateMultiThread类和WebContainer类.


import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//该类模拟多线程Servlet的情况
public class SmulateMultiThread implements Runnable{
public SmulateMultiThread() {
}
public static void main(String[] args) {
//处理100个请求
for(int i=0;i<100;i++)
{
new Thread(new SmulateMultiThread()).start();
}
}
public void run() {
HttpServletRequest request=null;
HttpServletResponse response=null;
try {
WebContainer.getServlet().doGet(request, response);
}
catch (IOException ex) {
}
catch (ServletException ex) {
}
}
}
//这是一个Servlet类
class UnsafeServlet extends HttpServlet{
private String unsafe;
public void init() throws ServletException {
}
//Process the HTTP Get request
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
unsafe=Thread.currentThread().getName();
System.out.println(unsafe);
}
}
//这个是容器类
class WebContainer{
private static UnsafeServlet us=new UnsafeServlet();
public static UnsafeServlet getServlet(){
return us;
}
}


输出了100不同的线程名称,如果有100个请求同时被这个Servlet处理的话,那么unsafe就可能有100种去值,最后客户端将得到错误的值.比如客户1请求的线程名为thread-1,但是返回给他的可能是thread-20.表现在现实中就是,我登陆的用户名是user1,登陆后变成了user2.

那么怎样才能是Servlet安全呢,凡是多个线程可以共享的就不要使用(实例变量+类变量),就这么简单.也可以使用synchronized同步方法,但是这样效率不高,还可以使用单线程模型,这样的话效率就更低了,100个请求同时来的时候就要实例化100个实例.

方法中的临时变量是不会影响线程安全的,因为他们是在栈上分配空间,而且每个线程都有自己私有的栈空间.

3.JSP中线程安全

JSP的本质是Servlet,所有只要明白了Servlet的安全问题,JSP的安全问题应该很容易理解.使用声明的变量是Servlet的实例变量,不是线程安全的,其他都是线程安全的.


<%! String unsafeVar; %>//不是线程安全的
<% String safeVar; %>// 线程安全的


总结:线程安全问题主要是由实例变量造成的,不管在Servlet还是JSP,或者在Struts的Action里面,不要使用实例变量,任何方法里面都不要出现实例变量,你的程序就是线程安全的.
    

 
 
(转载文章请保留出处:北天JAVA技术网(www.java114.com))
 
更多精彩文章:
Tomcat 服务器下 JSP 页面中文问题解答
JSP中的pageEncoding和contentType属性
对JSP中的内置对象简单概述
Eclipse NetBeans IntelliJ的实用对比
J2EE进阶:Spring框架的事务管理及应用
使用ActionForward优化Struts应用程序
 
最近评论:
        
你曾悄悄的来过!
wow gold,wow gold,wow gold,ffxi gil max(8130)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(139)
        
冰封的往事!
wow power leveling,wow gold,wow power leveling,wow gold max(2333)
        
冰封的往事!
wow power leveling,wow gold,WoW Gold,wow gold max(3761)
        
标 题:   
内 容:   
 
                                  
 
免责声明:该文章由网友发表,如果对您造成侵权,请联系站长

首页 - 承接项目 - 网站地图 - 联系我们 -
版权所有北天JAVA技术工作室 ICP证号:粤ICP备06079815号