TheOldDriver
8/6/2017 - 2:51 AM

sping的单例线程问题

sping的单例线程问题

//采用ThreadLocal保证变量的线程安全
public class SqlConnection {    
    //①使用ThreadLocal保存Connection变量    
    privatestatic ThreadLocal <Connection>connThreadLocal = newThreadLocal<Connection>();    
    publicstatic Connection getConnection() {    
       // ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection,    
       // 并将其保存到线程本地变量中。    
       if (connThreadLocal.get() == null) {    
           Connection conn = getConnection();    
           connThreadLocal.set(conn);    
           return conn;    
       } else {    
           return connThreadLocal.get();    
           // ③直接返回线程本地变量    
       }    
    }    
    public voidaddTopic() {    
       // ④从ThreadLocal中获取线程对应的Connection    
       try {    
           Statement stat = getConnection().createStatement();    
       } catch (SQLException e) {    
           e.printStackTrace();    
       }    
    }    
}  

对于实体bean的相关处理

由于springMVC默认是singleton的,所以会产生一个潜在的安全隐患.
根本核心是instance的变量保持状态的问题.
这意味着每个request过来,系统都会用原有的instance去 处理,这样有两个结果:

  1. 不用每次都创建`controller;
  2. 减少了对象的创建和垃圾收集的时间;

由于只有一个controllerinstance,当多个线程同时调用时,
controller 中的变量(可以理解为私有变量)就不是线程安全的了,会发生窜数据的问题. 因此,在使用controller时,应该避免在其中定义实例变量. 解决方法:

  1. 在控制器中不使用实例变量
  2. 将控制器的作用域从单例改为原型,@Scope("prototype")
  3. controller中使用ThreadLocal变量