struts2的action是线程安全的,struts1的action不是线程安全的真正原因

为什么struts2的action是线程安全的,struts1的action不是线程安全的? 
先对struts1和struts2的原理做一个简单的讲解

对于struts1 ,当第一次**.do的请求过来时,在内存中的actionmapping中找到相对应的action,然后new出这个action放在缓存中,当第二次一样的请求过来时,还是找的这个action,所以对于struts1来说,action是单实例的 ,只有一个,如果在action中定义变量,就要非常小心了,因为并发问题,可能带来灾难性的后果,也不是不可以,我们可以加锁达到同步,只是在性能上就要折衷了。

另外说几句 ,当struts交由spring管理的时候 ,spring的bean配置默认是单例的 , 
如果action是有状态的 ,必须显示的配置为prototype

Java代码  

  1. <bean id="saveUserAction" class="com.test.action.user.SaveUserAction" scope="prototype">
  2. <property name="service" ref="userService"></property>
  3. </bean>

下面是struts1.2的源码: 
当请求过来时,去找指定的action,如果有就直接取出来,如果没有就new一个新的action放到map中。

Java代码  

  1. /**
  2. * The set of Action instances that have been created and
  3. * initialized, keyed by the fully qualified Java class name of the
  4. * Action class.
  5. */
  6. protected HashMap actions = new HashMap();

processActionCreate这个方法里去一窥究竟吧: 
1、先获取类名 
2、根据类名去一个名为actions的map里查寻实例是否已经存在 
3、如果存在,则直接返回 
4、如果不存在,则创建一个新实例 
5、把创建好的action放到map里备用

Java代码  

  1. protected Action processActionCreate(HttpServletRequest request,
  2. HttpServletResponse response,
  3. ActionMapping mapping)
  4. throws IOException {
  5. // Acquire the Action instance we will be using (if there is one)
  6. String className = mapping.getType();//1、先获取类名
  7. ...
  8. Action instance = null;
  9. synchronized (actions) {
  10. // Return any existing Action instance of this class
  11. instance = (Action) actions.get(className);//2、根据类名去map里查寻实例是否已经存在
  12. if (instance != null) {
  13. return (instance); //3、如果存在,则直接返回
  14. }
  15. // Create and return a new Action instance
  16. //4、如果不存在,则创建一个新实例
  17. instance = (Action) RequestUtils.applicationInstance(className)
  18. instance.setServlet(this.servlet);
  19. actions.put(className, instance);//5、把创建好的action放到map里
  20. }
  21. ...
  22. return (instance);
  23. }

struts2 在struts1的基础上做了改进 ,对于struts2 ,每次请求过来都会new一个新的action , 所以说struts2的action是线程安全的 , 但同时也带来一个问题,每次都new一个action ,这样action的实例太多 , 在性能方面还是存在一定的缺陷的。

struts1是单例模式,而struts2是原型模式

时间: 2025-01-19 20:32:19

struts2的action是线程安全的,struts1的action不是线程安全的真正原因的相关文章

Struts2 源码分析——调结者(Dispatcher)之action请求

章节简言 上一章笔者讲到关于struts2启动的时候加载对应的准备工作.如加载配置文件struts.xml之类的信息.而相应的这些操作都离不开Dispatcher类的帮助.如果读者只是认为Dispatcher类的作用只有这些.那真的是大错特错了.所以本章笔者将继续讲到关于Dispatcher类的另一个功能.即是StrutsPrepareFilter类俩项工作中的处理request请求相关信息.在讲解之前,笔者还是想把相关的信息回想一下:当项目启动的时候,strtus2也就启动了.然后就会去初始化

struts2学习笔记之十四:使用注解配置Action(不是和spring集成使用)

Struts2支持使用注解配置Action,减少配置文件的配置 Struts2如果要支持注解配置Action,需要插件的支持,导入插件struts2-convention-plugin-2.1.8.1.jar 项目目录树: 1.导入struts2需要的基本包 2.修改web.xml,让struts2拦截Action <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="htt

Struts2 Convention插件的使用(4)使用@Action注解返回json数据

package com.hyy.action; import java.util.HashMap; import java.util.Map; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; imp

Struts2学习---namespace,file模块包含,默认action

我们上一节已经将action基本的配置和使用讲了,接下来我们讲以下struts一些小知识点: namespac: 上一节学习action的时候我们访问我们jsp文件时候使用的: http://localhost:8080/testStruts2/hello 这个路径,有同学就会问,为啥只能用这个路径, 其实我们也可以用: http://localhost:8080/testStruts2/hello.action 这两种是默认的方法,但是同样我们也可以自定义. <package name="

Struts1的Action继承不同的父类有不同的作用

1.ForwardAction:用于请求转发.   例如:锚点标记,为了保持MVC的结构,在使用锚点标记是不直接跳转页面,而是通过跳转到XX.do 由ForwardAction实现页面跳转.   配置: <action-mappings> <action path="/toLogin" type="org.apache.struts.actions.ForwardAction" forward="/login.jsp"> 

多线程(三) 实现线程范围内模块之间共享数据及线程间数据独立(ThreadLocal)

ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.JDK 1.2的版本中就提供java.lang.ThreadLocal,使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量. 1.下图和辅助代码解释ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据. 2.每个线程调用全局ThreadLocal

Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理 以下是本文的目录大纲: 一.shutdown()  --  温柔的终止线程池 interruptIdleWorkers()  --  中断空闲worker tryTerminate()  --  尝试终止线程池 二.shutdown

Google面试题—有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD

分类: windows编程 C++ 2012-10-27 19:56 3410人阅读 评论(1) 收藏 举报 有四个线程1.2.3.4.线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD.初始都为空.现要让四 个文件呈如下格式:A:1 2 3 4 1 2....B:2 3 4 1 2 3....C:3 4 1 2 3 4....D:4 1 2 3 4 1....请设计程序. [cpp] view plaincopy #include <stdio.h

使用$_GET[&quot;action&quot;]取值时必须先判断action是否存在。

使用$_GET["action"]取值时必须先判断action是否存在. if (isset($_GET["action"]) && $_GET["action"]=="register"){ //获取一个键值对判断提交数据是否成功 echo "提交数据成功!"; exit(); ($_POST[ ]同上)