servlet,struts2线程安全问题浅析

来源:互联网 发布:centos 7登录 编辑:程序博客网 时间:2024/06/05 07:00

                                                      servlet struts2线程安全问题浅析

Servlet体系结构是建立在Java多线程机制之上的,它的生命周期是由Web容器负责的。当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。那在这个实例的全局变量就是共有的,所以servlet线程安全问题主要是由实例变量造成的,因此在Servlet中应避免使用实例变量。如果应用程序设计无法避免使用实例变量,那么使用同步来保护要使用的实例变量,但为保证系统的最佳性能,应该同步可用性最小的代码路径。

现在做个项目,因为新来的同事只会struts2,所以第一次用,没有研究太细的研究过,所以今天在用struts2中遇到这样一问题,在做分页的时候,把页面numPage让他自动接收全局变量,让struts2自动注入,然后问题就出现了,如果不对进行注入的时候,那么numPage就会留在上一次注入的值。如果把numPage该能局部的,问题解决了。看来以后变化的常量最好不用用全局的。

《strut2权威指南》中有这么一段:
线程模式方面的对比:Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能做的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的;Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题 。

都产生一个实例,所以说全局的变量应该是共享的。

具体的,还是等有时间了研究下struts2的源码在发出来。

 
我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:
1)常量始终是线程安全的,因为只存在读操作。
2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。

3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。




常见的线程安全的解决办法:
1.使用方法内局部变量

  • 是因为各线程有自己堆栈空间,存储局部变量
  • 方法参数传入,多采用传值(volue copy)传入方法内

2.对操作共享资源的语句,方法,对象,使用同步
比如写入磁盘文件,采用同步锁,但建议尽量用同步代码块,不要用同步方法


3.使用同步的集合类
使用Vector代替ArrayList
使用Hashtable代替HashMap。

4.不要在 Servlet中再创建自己的线程来完成某个功能。
Servlet本身就是多线程的,在Servlet中再创建线程,将导致执行情况复杂化

0 0
原创粉丝点击