zoukankan      html  css  js  c++  java
  • Spring框架中的单例Beans是线程安全的么

    Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。

    最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。

    没太看懂有状态和无状态的bean是什么意思,于是百度之,获益匪浅。

    在Spring的Bean配置中,存在这样两种情况:

    1. <bean id="testManager" class="com.sw.TestManagerImpl" scope="singleton" />  
    2.   
    3.  <bean id="testManager" class="com.sw.TestManagerImpl" scope="prototype" />  

    当然,scope的值不止这两种,还包括了request,session 等。但用的最多的还是singleton单态,prototype多态。

    singleton表示该bean全局只有一个实例,Spring中bean的scope默认也是singleton.

    prototype表示该bean在每次被注入的时候,都要重新创建一个实例,这种情况适用于有状态的Bean.

    对于SSH架构的系统,很少关心这方面,因为我们用到的一般都是singleton. Bean的注入由Spring管理。

    对于有状态的Bean呢?

    下面是一个有状态的Bean

    1. package com.sw;  
    2.   
    3. public class TestManagerImpl implements TestManager{  
    4.     private User user;    
    5.   
    6.     public void deleteUser(User e) throws Exception {  
    7.         user = e ;           //1  
    8.         prepareData(e);  
    9.     }  
    10.   
    11.     public void prepareData(User e) throws Exception {  
    12.         user = getUserByID(e.getId());            //2  
    13.         .....  
    14.         //使用user.getId();                       //3  
    15.         .....  
    16.         .....  
    17.     }     
    18. }  

    如果该Bean配置为singleton,会出现什么样的状况呢?

    如果有2个用户访问,都调用到了该Bean.

    假定为user1,user2

    当user1 调用到程序中的1步骤的时候,该Bean的私有变量user被付值为user1

    当user1的程序走到2步骤的时候,该Bean的私有变量user被重新付值为user1_create

    理想的状况,当user1走到3步骤的时候,私有变量user应该为user1_create;

    但如果在user1调用到3步骤之前,user2开始运行到了1步骤了,由于单态的资源共享,则私有变量user被修改为user2

    这种情况下,user1的步骤3用到的user.getId()实际用到是user2的对象。

    而如果是prototype的话,就不会出现资源共享的问题。

    对于SSH来说,Bean的配置是没错的,配置为singleton ;实际应该是这个例子不应该用私有变量。这样就使得这个Bean

    由无状态变成了有状态Bean.还是应该尽量使用无状态Bean.如果在程序中出现私有变量,尽量替换为参数。
    对于每个访问私有变量的方法增加变量传入或者通过ThreadLocal来获取也是不错的方法。

    真正出现上面代码问题的也是少数,出现的时候,一般是为了图方便,一个很多方法都要用到的变量,如果都需要用参数的

    方式传递多麻烦呀,这样私有变量多好,不用参数那样丑陋。但是丑陋并不代表不好,以对的,自己习惯的方式编程,才能

    尽量避免问题的发生。

  • 相关阅读:
    POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)
    LCA 最近公共祖先 (模板)
    线段树,最大值查询位置
    带权并查集
    转负二进制
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    UVALive 3295 Counting Triangles
    POJ 2752 Seek the Name, Seek the Fame (KMP)
    UVA 11584 Partitioning by Palindromes (字符串区间dp)
  • 原文地址:https://www.cnblogs.com/nangonghui/p/8988640.html
Copyright © 2011-2022 走看看