我的日常

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > Struts1和Struts 2线程安全问题
总共48086条微博

动态微博

查看: 1130|回复: 0

Struts1和Struts 2线程安全问题

[复制链接]
admin    

1244

主题

544

听众

1万

金钱

管理员

  • TA的每日心情

    2021-2-2 11:21
  • 签到天数: 36 天

    [LV.5]常住居民I

    管理员

    跳转到指定楼层
    楼主
    发表于 2015-05-07 09:11:32 |只看该作者 |倒序浏览
    问题:
    7 u0 n2 ]+ Z* C5 c$ |struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。- J2 W, @* ^6 @: S' ~$ |  w
    spring的Ioc容器管理的bean默认是单实例的,上一次请求处理的状态信息被保持下来,并影响了下一次的请求,实际上就是Action中的类变量被不同的请求读取,出现错误结果
    + N* e: Y1 U$ a$ c% O: {" U* G7 d- V. _: ]) k, S
    解决:就是不用单例, spring中bean的作用域设为prototype,每个请求对应一个实例.' K9 Z. W' r# ?+ `: a# y

    $ l+ O$ U/ K( S$ c8 h1、Struts1
    0 z3 P, z% Y! S1 RStruts1是单例模式,也就是所,Web容器(例如:Tomcat)启动的时候,就会实例化一个Action对象,那么所有请求都是用的这个对象。所以当遇到2个请求并发的时候,那么其实他们调用的是同一个类,这个时候当你在Action内部定义属性的时候,就会产生线程同步的问题。
    & l+ q$ F  H; S& E4 M0 x例如:
    - b0 ~+ ]; U- j3 c' B8 X( H0 Q你在Action定义了一个 int i = 0;
    & R$ y3 D" u; \6 S然后在这个Action里面的某一个方法里面对这个i进行操作。当并发的时候就会遇到问题。
    3 |4 [; z% L+ [! U1 |' {% @所以:我们在用struts1的时候不能在action里面定义属性。要用到只的话只能在方法里面定义。  X/ I' y7 |  P8 V
    2、struts2# M: W! i: W& F
    Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。所以我们可以在Struts2的Action里面去定义属性。但是Struts2由于 Action和普通的java类没有任何区别(也就是不用像Struts1里面那样去实现一个Struts的接口,有兴趣的朋友可以自己去了解),所以我们可以用Spring去管理Struts2的Action,这个时候我们就要注意了,因为当我们在spring里面去定义bean的时候,spring默认用的是单例模式。所以在这个时候,你就要修改Spring的配置文件---即修改scope为prototype。
    4 V# V) d, O$ |! s$ X为什么struts1中并没有考虑到线程问题,因为所有的代码都是写在execute的方法中,所有变量都是定义在里面,所以没有线程安全问题。  m  Z) X: [! D6 T; A+ X2 x" ^4 Q: j
    而现在的struts2就不一样了。struts2的action中就像一个POJO一样,定义了很多的类变量。这就有线程安全问题了。。此时,就使用scope=prototype来指定是个原型模式,而不是单例,这样就解决了线程安全问题。每个线程都是一个新的实例。。5 N1 I; m( N7 A% W; ?& L
    7 @$ L, E7 n  o5 r& P& _
    但是,线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同步在编写容易度和性能上会更好些。
    & D1 n; ^( `$ G: t我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:" [- Y+ ]! C2 ]2 R$ O4 R
    1)常量始终是线程安全的,因为只存在读操作。$ s6 C/ B; E. ^! |5 L5 e* p9 Q7 D
    2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。1 \. H3 x$ W" L' c( _* y
    3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。
    : t& o5 x2 E( c+ q4 ^1 Tstruts user guide里有:0 p8 A7 Q0 L7 P3 I% B; Y2 L* h
    Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.
      r, P" k% e3 h: i/ ~) F+ e) X译:只使用用局部变量。--编写线程安全的代码最重要的原则就是,在Action类中只使用局部变量,不使用实例变量。
    6 B7 _& `7 p: V9 e' M0 o! O( Q
    - v: Q/ J/ R$ A" h; H9 l

    科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、科帮网管理员和版主有权不事先通知发贴者而删除本文


    JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

    快速回复
    您需要登录后才可以回帖 登录 | 立即注册

       

    关闭

    站长推荐上一条 /1 下一条

    发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
    快速回复 返回顶部 返回列表