struts2 的线程安全

问题:

Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。

Spring的Ioc容器管理的bean默认是单实例的,上一次请求处理的状态信息被保持下来,并影响了下一次的请求,实际上就是Action中的类变量被不同的请求读取,出现错误结果

解决:就是不用单例, spring中bean的作用域设为prototype,每个请求对应一个实例.

1、Struts1

Struts1是单例模式,也就是所,Web容器(例如:Tomcat)启动的时候,就会实例化一个Action对象,那么所有请求都是用的这个对象。所以当遇到2个请求并发的时候,那么其实他们调用的是同一个类,这个时候当你在Action内部定义属性的时候,就会产生线程同步的问题。

例如:

你在Action定义了一个 int i = 0;

然后在这个Action里面的某一个方法里面对这个i进行操作。当并发的时候就会遇到问题。

所以:我们在用struts1的时候不能在action里面定义属性。要用到只的话只能在方法里面定义。

2、struts2

Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。所以我们可以在Struts2的Action里面去定义属性。但是Struts2由于 Action和普通的Java类没有任何区别(也就是不用像Struts1里面那样去实现一个Struts的接口,有兴趣的朋友可以自己去了解),所以我们可以用Spring去管理Struts2的Action,这个时候我们就要注意了,因为当我们在spring里面去定义bean的时候,spring默认用的是单例模式。所以在这个时候,你就要修改Spring的配置文件---即修改scope为prototype。

为什么struts1中并没有考虑到线程问题,因为所有的代码都是写在execute的方法中,所有变量都是定义在里面,所以没有线程安全问题。

而现在的struts2就不一样了。struts2的action中就像一个POJO一样,定义了很多的类变量。这就有线程安全问题了。。此时,就使用scope=prototype来指定是个原型模式,而不是单例,这样就解决了线程安全问题。每个线程都是一个新的实例。。

但是,线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同步在编写容易度和性能上会更好些。

我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:

1)常量始终是线程安全的,因为只存在读操作。

2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。

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

struts user guide里有:

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.

译:只使用用局部变量。--编写线程安全的代码最重要的原则就是,在Action类中只使用局部变量,不使用实例变量。

时间: 2024-10-22 12:08:20

struts2 的线程安全的相关文章

【转】Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式

[转]Struts2的线程安全 和Struts2中的设计模式----ThreadLocal模式 博客分类: 企业应用面临的问题 java并发编程 Struts2的线程安全ThreadLocal模式Struts2调用流程 转载自  http://downpour.iteye.com/blog/1335991 Struts2中的设计模式 设计模式(Design pattern)是经过程序员反复实践后形成的一套代码设计经验的总结.设计模式随着编程语言的发展,也由最初的“编程惯例”逐步发展成为被反复使用

Servlet和Struts2的线程安全问题

通常情况下,系统只生成servlet的单一实例之后,为每个用户请求建立新的线程.如果很多请求同时到来,那么多个线程可能会并发的访问同一个servlet对象.servlet是线程不安全的,在多线程访问servlet的时候,有一些限制: 尽量不要有成员变量: 如果有成员变量,这个成员变量也要是无状态的成员变量: 如果非要有成员变量,这个成员变量只能是只读的: struts2本身就是多实例.单线程的,所以可以说本身就是线程安全的. (Action是线程安全的,因为struts2中,action是多例的

为什么原生的servlet是线程不安全的而Struts2是线程安全的?

因为原生的servlet在整个application生命周期中,只在初次访问的时候实例化一次,以后都不会再实例化,只会调用Server方法进行响应,所以如果在servlet类中定义成员变量,那么就会让每个访问的用户的都共享了此成员变量数据,既然是共享,那么任何一个人修改都会造成其他人数据的改变,所以servlet年代,成员变量是不能作为参数存放的,只能在具体每个线程访问的方法中单独获取方法定义变量接收才能保证线程安全,而Struts2是每次request访问时都会实例化一次对应action,当前

实际工作中遇到关于Struts2线程安全的问题解决

今天工作遇到一个难缠的bug,浪费了2个小时终于解决. 问题描述:对资源的管理中用到关键字查询以及分页查询.视图控制器用到struts2,数据存储用spring的data-mongodb来存储数据以及查询数据.但是发现一个问题,在用分页查询时能查询出所有记录,然后用关键字查询获取查询内容后,在用分页查询但是只能获取关键查询的数据,其他数据死活查询不出来.开始我以为是自己前端有逻辑问题,但是我用其他的浏览器操作同样出问题.因此知道问题出在后台代码.开始以为是不是数据有缓存,但是其他模块也这样实现没

Struts1、Struts2和SpringMVC剖析

前段框架用了不少,今天就来做个总结.网上关于Struts1.Struts2.SpringMVC的文章有很多,这里的内容就是基于它们,来做个比较. 这三个框架是按照上面的顺序,依次出现的,它们都是对MVC模式的实现.为什么会出现这三个.甚至更多的MVC框架呢?他们都是为了将URL世界映射到Java世界.尽管它们它们内部的实现思路不同,有着各自的优缺点,但是它们都做到了个自己的使用目的. 历史介绍 大多Web应用程序,都是运行在HTTP上的.HTTP协议是一系列无状态的文本传输协议.无状态的协议不记

ThreadLocal(关于struts2的ThreadLocal,实际上Jdk1.2就有了)

ThreadLocal是通过在不同线程中操作变量的副本,来达到线程安全的目的,是用空间资源换时间资源的方式.今天在看struts2源码的时候,发现ActionContext中,就持有一个静态的ThreadLocal,如下: public class ActionContext implements Serializable { static ThreadLocal actionContext = new ThreadLocal();} 所以推测一下struts2实现线程安全的方式也采用了这种方法

【Struts2】★☆之struts2的处理流程和对Action的管理方式

[Struts2]★☆之struts2的处理流程和对Action的管理方式 首先我们先来看一张我画的草图,如下: 接下来,是一个web.xml配置文件的常用代码 <filter>         <filter-name>struts2</filter-name>         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</fi

Struts1、WebWork、Struts2介绍

一.Struts1 1.Struts1原理简介 Struts1框架以ActionServlet作为控制器核心,整个应用由客户端请求驱动.当客户端向Web应用发送请求时,请求被Struts1的核心控制器ActionServlet拦截,ActionServlet根据请求决定是否需要调用业务逻辑控制器处理用户请求(实际上,业务逻辑控制器还是控制器,它只是负责调用模型来处理用户请求),当用户请求处理完成后,其处理结果会通过jsp呈现给用户. Struts1,控制器就是它的核心,Struts1的控制器分为

Struts1、Struts2和SpringMVC

这三个框架是按照上面的顺序,依次出现的,它们都是对MVC模式的实现.为什么会出现这三个.甚至更多的MVC框架呢?他们都是为了将URL世界映射到Java世界.尽管它们它们内部的实现思路不同,有着各自的优缺点,但是它们都做到了个自己的使用目的. 历史介绍 大多Web应用程序,都是运行在HTTP上的.HTTP协议是一系列无状态的文本传输协议.无状态的协议不记录收到的多个请求之间的关系,也就是说服务器与相应客户端如何对应起来,是一个问题.此外,HTTP是基于文本的.如何将基于文本的技术与强类型的Java