1.线程安全的代码

在多线程环境下能正确执行的代码是线程安全的,所谓安全指能正确执行。

2.始终为线程安全的、不需要同步的代码:

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

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

3)局部变量是线程安全的。因为局部变量存储在每个线程的工作内存的堆栈中,每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。

因此,在JavaWeb服务器环境下开发,要注意线程安全的问题,最简单的方式就是在ServletStrutsAction里只使用局部变量,不要使用类变量、实例变量,但可以使用类常量和实例常量。如果有这些变量,将他们转换为方法的参数传入,以消除它们。

3.Struts1的线程安全

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

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

4.Struts2的线程安全

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

为什么struts1中并没有考虑到线程问题,因为所有的代码都是写在execute的方法中,所有变量都是定义在里面,所以没有线程安全问题。而struts2的action中就像一个POJO一样,定义了很多的类变量,这就有线程安全问题了。此时,就使用scope=prototype来指定是个原型模式,而不是单例,这样就解决了线程安全问题。每个线程都是一个新的实例。