就是在beans.xml中定义的,比如<bean id="admindao" class="DAO.impl.AdminDaoImpl"></bean>这个类DAO.impl.AdminDaoImpl,我调用时是线程安全的吗?再有,整合struts和spring时,可以把struts的action纳入spring容器管理,比如<bean name="/logindeal" class="action.Logindeal"></bean>,这里的/logindeal是个action。因为action是线程不安全的,那么我想知道这样纳入spring容器后是不是就线程安全了?如果以上都是线程不安全的,那么怎么做(尤其是整合struts和spring的)能保证线程安全?

解决方案 »

  1.   

    关于楼主的疑问不如看看TreadLocal的源代码,就了解了。 
    其实就是一个大Map,里面用Thread id作为key,存Object。 
    这样对于非线程安全的hibernate session、transaction status等通过treadlocal保存就可以保证每个线程都有独立的这些object实例了,也就不存在线程安全问题了。只有那些有状态的单例组件才存在线程安全问题 什么是有状态的组件:存在可变的实例变量 所以,如果你的spring pojo只是有一些像datasource或者sessionfactory这样的不变的实例变量,那么即使它是单例也不用担心线程安全问题 
    以前有人解释过,TreadLoacl的想法就是把资源私有化的容器。以此类推其它方案。
      

  2.   

    也没必要偏要spring是线程安全的,你写的action是线程安全就行了spring好像默认是线程安全的,有个singlton属性配置吧
      

  3.   

    我是楼主,问题是这样的,整合了struts和spring后,我现在的action里面有属性,属性是依赖注入的。
    比如:
    public class deal extends Action { @Resource
    AdminDao admindao;

    public ActionForward execute(ActionMapping mapping, ActionForm form,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception {

    admindao.getXXXX();
                    ......
    }
    }
    我在beans.xml里面定义接口admindao的实例,然后依赖注入,用到注解。
    我想知道,这样的话会不会线程不安全?AdminDao admindao这样定义的变量在struts中是线程不安全的,那么现在呢?
      

  4.   

    我是二楼的
    刚查了下spring的书,spring默认是单例模式,但它会对非线程安全的变量进行特殊处理,也就是利用AOP和LocalThread类进行转变,使其成为线程安全的类。
      

  5.   

    还有,JdbcTemplate和LobHandler是线程安全的么?比如这样写是否线程安全:
    public class PersonServiceBean implements PersonService { private JdbcTemplate jdbcTemplate;
    private LobHandler lobHandler; public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new JdbcTemplate(dataSource);
    }        public void delete(int personid) throws Exception {
    jdbcTemplate.update(.....);
    }
    }
      

  6.   

    如果是单例模式的,那最好不要在action中设置属性(类似无状态的),只要方法就可以
    这样的话就不会存在比较安全问题了。即使多线程一起调用也没关系
      

  7.   

    假设你的
    dao里有一个private Session s,那么你如果用spring默认的singlton来配置dao就会出问题,像Session这样的非线程安全的变量,不同的线程程是不能共享的如果dao的变量是private SessionFactory sf,或者hibernateTemplate,这样允许共享的只读变量
    那么dao就可以配置成singlton
    -------------------
    最常见的实例是struts2的action,因为action的成员变量要保存表单的输入值,如果struts2的action配置成单例,那么不同的请求就会相互覆盖action的属性值,出现线程安全问题,所以对于持有有状态属性的bean,一般配置成protocol而对于struts1,他的action里一般没有有状态的属性,所以配置成单例或者protocol都可以
      

  8.   

    1 struts1的action是单例的,所以存在线程安全问题
    2 spring默认的注入也是单例的,所以也存在线程安全问题先理解为何会有线程不安全的问题,比如有一个类Person 有个属性是name,线程1修改了这个属性的name,要进行存入数据库操作的时候,线程2又修改了这个name,这样线程1就存入了一个线程2修改过的数据了。避免的方法很简单
     struts1如果被spring管理,那么可以设置成scope为protype,这样action就不是单例了,而是为每个线程都创建一个;
     线程安全是可以避免的,就是禁止用可变动的成员变量,如果都是局部变量的话,即使是单例的也不存在任何问题private JdbcTemplate jdbcTemplate;
    private LobHandler lobHandler; 
    里面没什么可变成员变量,说以他们是单例的,但是不会有线程问题
      

  9.   

    同意10楼的1.首先楼主要理解为什么会产生线程不安全的情况,然后再去考虑一个类是否线程安全
    2.其次,线程是否安全,其实和spring、struts没有必然关系
      你说struts的action不是线程安全的,那是因为你在action里定义了属性
      比如:
    public class SampleAction extends Action {
        private String user = null;
        ...
    }  如果有多个用户上来访问这个SampleAction,而且每个用户都要来修改user属性或者说是要对user进行某种操作,那么这就是一种线程不安全的情况,或者说是场景。
        但是,如果你不定义这个user属性,也不定义任何其他属性,那么这个SampleAction就不存在线程不安全的问题。还有种情况,如果你这个属性定义成final的,只是在初始化的时候进行一次赋值,以后所有的操作都只是读取、而不会修改这个属性的值,那么也不会有线程安全的问题。    再比如,有一个类User,你每次使用这个类的时候都是new出来的,那么这个类一定是线程安全的吗?也不一定。
    public class User {
        private static String name = null;
        
        public User(String name) {
            User.name = name;
        }
    }    对于这个User类,即使你每次都是new一个新的,它也不是线程安全的。